mirror of
https://github.com/ENSL/ensl.org.git
synced 2024-11-14 00:40:49 +00:00
Purged git history and removed sensitive information.
This commit is contained in:
commit
6bcc8dc76b
862 changed files with 25312 additions and 0 deletions
8
.env.sample
Normal file
8
.env.sample
Normal file
|
@ -0,0 +1,8 @@
|
|||
UNICORN_WORKERS=3
|
||||
UNICORN_PORT=5000
|
||||
UNICORN_SOCKET=/tmp/unicorn.ensl.sock
|
||||
|
||||
APP_SECRET=
|
||||
|
||||
MYSQL_USERNAME=
|
||||
MYSQL_PASSWORD=
|
40
.gitignore
vendored
Normal file
40
.gitignore
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Rails, etc
|
||||
/coverage/
|
||||
/log/*
|
||||
/tmp/*
|
||||
/spec/tmp/*
|
||||
.env
|
||||
.tmp*
|
||||
.rspec
|
||||
.sass-cache
|
||||
*.sassc
|
||||
*.rbc
|
||||
*.sassc
|
||||
|
||||
# OS X
|
||||
.DS_Store
|
||||
|
||||
# Assets
|
||||
/public/system/*
|
||||
/public/files
|
||||
/public/files/*
|
||||
/public/local
|
||||
|
||||
# RubyMine
|
||||
/.idea
|
||||
|
||||
# VIM
|
||||
**.swp
|
||||
|
||||
# Git junk
|
||||
**.orig
|
||||
|
||||
# Bundler
|
||||
/.bundle
|
||||
/vendor/bundle/
|
||||
.bundle
|
||||
|
||||
# Misc
|
||||
/index/*
|
||||
rerun.txt
|
||||
pickle-email-*.html
|
1
.ruby-version
Normal file
1
.ruby-version
Normal file
|
@ -0,0 +1 @@
|
|||
2.1.1
|
7
Capfile
Normal file
7
Capfile
Normal file
|
@ -0,0 +1,7 @@
|
|||
require 'capistrano/setup'
|
||||
require 'capistrano/deploy'
|
||||
require 'capistrano/rbenv'
|
||||
require 'capistrano/bundler'
|
||||
require 'capistrano/rails'
|
||||
|
||||
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
|
52
Gemfile
Normal file
52
Gemfile
Normal file
|
@ -0,0 +1,52 @@
|
|||
source 'http://rubygems.org'
|
||||
|
||||
ruby '2.1.1'
|
||||
|
||||
gem 'rails', '~> 3.2.16'
|
||||
gem 'mysql2', '~> 0.3.15'
|
||||
|
||||
# Deployment
|
||||
gem 'foreman', '~> 0.63.0'
|
||||
gem 'capistrano', '~> 3.1.0'
|
||||
gem 'capistrano-rbenv', '~> 2.0.2'
|
||||
gem 'capistrano-bundler', '~> 1.1.2'
|
||||
gem 'capistrano-rails', '~> 1.1'
|
||||
|
||||
# Libraries
|
||||
gem 'jquery-rails'
|
||||
gem 'sass-rails'
|
||||
gem 'coffee-rails'
|
||||
gem 'gruff'
|
||||
gem 'nokogiri'
|
||||
gem 'carrierwave'
|
||||
gem 'rbbcode'
|
||||
gem 'tinymce-rails'
|
||||
gem 'bluecloth', '~> 2.2.0'
|
||||
gem 'bb-ruby'
|
||||
gem 'therubyracer'
|
||||
gem 'acts_as_indexed'
|
||||
gem 'rmagick', require: false
|
||||
gem 'will_paginate', git: 'https://github.com/p7r/will_paginate.git', branch: 'rails3'
|
||||
gem 'newrelic_rpm', '~> 3.7.2.195'
|
||||
|
||||
group 'staging', 'production' do
|
||||
gem 'unicorn', '~> 4.8.2'
|
||||
end
|
||||
|
||||
group 'development' do
|
||||
gem 'annotate', '~> 2.6.2'
|
||||
end
|
||||
|
||||
group 'test' do
|
||||
gem 'simplecov', '~> 0.7.1', require: false
|
||||
gem 'rspec-rails', '~> 2.14.1'
|
||||
gem 'rspec-given', '~> 3.5.4'
|
||||
gem 'capybara', '~> 2.2.1'
|
||||
gem 'poltergeist', '~> 1.5.0'
|
||||
gem 'factory_girl_rails', '~> 4.4.1'
|
||||
end
|
||||
|
||||
group 'development', 'test' do
|
||||
gem 'pry-debugger', '~> 0.2.2'
|
||||
gem 'dotenv-rails', '~> 0.10.0'
|
||||
end
|
275
Gemfile.lock
Normal file
275
Gemfile.lock
Normal file
|
@ -0,0 +1,275 @@
|
|||
GIT
|
||||
remote: https://github.com/p7r/will_paginate.git
|
||||
revision: 53d1da6da003dc172ee054e4cc416d0723f00b88
|
||||
branch: rails3
|
||||
specs:
|
||||
will_paginate (3.0.pre3)
|
||||
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.17)
|
||||
actionpack (= 3.2.17)
|
||||
mail (~> 2.5.4)
|
||||
actionpack (3.2.17)
|
||||
activemodel (= 3.2.17)
|
||||
activesupport (= 3.2.17)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.5)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.2.1)
|
||||
activemodel (3.2.17)
|
||||
activesupport (= 3.2.17)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.17)
|
||||
activemodel (= 3.2.17)
|
||||
activesupport (= 3.2.17)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.17)
|
||||
activemodel (= 3.2.17)
|
||||
activesupport (= 3.2.17)
|
||||
activesupport (3.2.17)
|
||||
i18n (~> 0.6, >= 0.6.4)
|
||||
multi_json (~> 1.0)
|
||||
acts_as_indexed (0.7.8)
|
||||
annotate (2.6.2)
|
||||
activerecord (>= 2.3.0)
|
||||
rake (>= 0.8.7)
|
||||
arel (3.0.3)
|
||||
bb-ruby (0.9.5)
|
||||
bluecloth (2.2.0)
|
||||
builder (3.0.4)
|
||||
capistrano (3.1.0)
|
||||
i18n
|
||||
rake (>= 10.0.0)
|
||||
sshkit (~> 1.3)
|
||||
capistrano-bundler (1.1.2)
|
||||
capistrano (~> 3.0)
|
||||
sshkit (~> 1.2)
|
||||
capistrano-rails (1.1.1)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-bundler (~> 1.1)
|
||||
capistrano-rbenv (2.0.2)
|
||||
capistrano (~> 3.1)
|
||||
sshkit (~> 1.3)
|
||||
capybara (2.2.1)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
xpath (~> 2.0)
|
||||
carrierwave (0.6.2)
|
||||
activemodel (>= 3.2.0)
|
||||
activesupport (>= 3.2.0)
|
||||
cliver (0.3.2)
|
||||
coderay (1.1.0)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (~> 3.2.0)
|
||||
coffee-script (2.2.0)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.3.3)
|
||||
columnize (0.3.6)
|
||||
debugger (1.6.6)
|
||||
columnize (>= 0.3.1)
|
||||
debugger-linecache (~> 1.2.0)
|
||||
debugger-ruby_core_source (~> 1.3.2)
|
||||
debugger-linecache (1.2.0)
|
||||
debugger-ruby_core_source (1.3.2)
|
||||
diff-lcs (1.2.5)
|
||||
dotenv (0.10.0)
|
||||
dotenv-rails (0.10.0)
|
||||
dotenv (= 0.10.0)
|
||||
erubis (2.7.0)
|
||||
execjs (1.4.0)
|
||||
multi_json (~> 1.0)
|
||||
factory_girl (4.4.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_girl_rails (4.4.1)
|
||||
factory_girl (~> 4.4.0)
|
||||
railties (>= 3.0.0)
|
||||
foreman (0.63.0)
|
||||
dotenv (>= 0.7)
|
||||
thor (>= 0.13.6)
|
||||
foreman (0.63.0-x86-mingw32)
|
||||
dotenv (>= 0.7)
|
||||
thor (>= 0.13.6)
|
||||
win32console (~> 1.3.0)
|
||||
given_core (3.5.4)
|
||||
sorcerer (>= 0.3.7)
|
||||
gruff (0.3.6)
|
||||
hike (1.2.3)
|
||||
i18n (0.6.9)
|
||||
journey (1.0.4)
|
||||
jquery-rails (2.0.2)
|
||||
railties (>= 3.2.0, < 5.0)
|
||||
thor (~> 0.14)
|
||||
json (1.8.1)
|
||||
kgio (2.9.2)
|
||||
libv8 (3.16.14.3)
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
multi_json (1.8.4)
|
||||
mysql2 (0.3.15)
|
||||
net-scp (1.1.2)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (2.8.0)
|
||||
newrelic_rpm (3.7.2.195)
|
||||
nokogiri (1.5.5)
|
||||
nokogiri (1.5.5-x86-mingw32)
|
||||
poltergeist (1.5.0)
|
||||
capybara (~> 2.1)
|
||||
cliver (~> 0.3.1)
|
||||
multi_json (~> 1.0)
|
||||
websocket-driver (>= 0.2.0)
|
||||
polyglot (0.3.4)
|
||||
pry (0.9.12.6)
|
||||
coderay (~> 1.0)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
pry (0.9.12.6-x86-mingw32)
|
||||
coderay (~> 1.0)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
win32console (~> 1.3)
|
||||
pry-debugger (0.2.2)
|
||||
debugger (~> 1.3)
|
||||
pry (~> 0.9.10)
|
||||
rack (1.4.5)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-ssl (1.3.3)
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.17)
|
||||
actionmailer (= 3.2.17)
|
||||
actionpack (= 3.2.17)
|
||||
activerecord (= 3.2.17)
|
||||
activeresource (= 3.2.17)
|
||||
activesupport (= 3.2.17)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.17)
|
||||
railties (3.2.17)
|
||||
actionpack (= 3.2.17)
|
||||
activesupport (= 3.2.17)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
raindrops (0.13.0)
|
||||
rake (10.1.1)
|
||||
rbbcode (0.1.11)
|
||||
sanitize-url (>= 0.1.3)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
ref (1.0.5)
|
||||
rmagick (2.13.1)
|
||||
rspec (2.14.1)
|
||||
rspec-core (~> 2.14.0)
|
||||
rspec-expectations (~> 2.14.0)
|
||||
rspec-mocks (~> 2.14.0)
|
||||
rspec-core (2.14.8)
|
||||
rspec-expectations (2.14.5)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-given (3.5.4)
|
||||
given_core (= 3.5.4)
|
||||
rspec (>= 2.12)
|
||||
rspec-mocks (2.14.6)
|
||||
rspec-rails (2.14.1)
|
||||
actionpack (>= 3.0)
|
||||
activemodel (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 2.14.0)
|
||||
rspec-expectations (~> 2.14.0)
|
||||
rspec-mocks (~> 2.14.0)
|
||||
sanitize-url (0.1.4)
|
||||
sass (3.1.20)
|
||||
sass-rails (3.2.5)
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
simplecov (0.7.1)
|
||||
multi_json (~> 1.0)
|
||||
simplecov-html (~> 0.7.1)
|
||||
simplecov-html (0.7.1)
|
||||
slop (3.4.7)
|
||||
sorcerer (1.0.2)
|
||||
sprockets (2.2.2)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sshkit (1.3.0)
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh
|
||||
term-ansicolor
|
||||
term-ansicolor (1.3.0)
|
||||
tins (~> 1.0)
|
||||
therubyracer (0.12.1)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
thor (0.18.1)
|
||||
tilt (1.4.1)
|
||||
tins (1.0.1)
|
||||
tinymce-rails (3.5.4.1)
|
||||
railties (>= 3.1.1)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.38)
|
||||
unicorn (4.8.2)
|
||||
kgio (~> 2.6)
|
||||
rack
|
||||
raindrops (~> 0.7)
|
||||
websocket-driver (0.3.2)
|
||||
win32console (1.3.2-x86-mingw32)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
x86-mingw32
|
||||
|
||||
DEPENDENCIES
|
||||
acts_as_indexed
|
||||
annotate (~> 2.6.2)
|
||||
bb-ruby
|
||||
bluecloth (~> 2.2.0)
|
||||
capistrano (~> 3.1.0)
|
||||
capistrano-bundler (~> 1.1.2)
|
||||
capistrano-rails (~> 1.1)
|
||||
capistrano-rbenv (~> 2.0.2)
|
||||
capybara (~> 2.2.1)
|
||||
carrierwave
|
||||
coffee-rails
|
||||
dotenv-rails (~> 0.10.0)
|
||||
factory_girl_rails (~> 4.4.1)
|
||||
foreman (~> 0.63.0)
|
||||
gruff
|
||||
jquery-rails
|
||||
mysql2 (~> 0.3.15)
|
||||
newrelic_rpm (~> 3.7.2.195)
|
||||
nokogiri
|
||||
poltergeist (~> 1.5.0)
|
||||
pry-debugger (~> 0.2.2)
|
||||
rails (~> 3.2.16)
|
||||
rbbcode
|
||||
rmagick
|
||||
rspec-given (~> 3.5.4)
|
||||
rspec-rails (~> 2.14.1)
|
||||
sass-rails
|
||||
simplecov (~> 0.7.1)
|
||||
therubyracer
|
||||
tinymce-rails
|
||||
unicorn (~> 4.8.2)
|
||||
will_paginate!
|
51
INSTALL.md
Normal file
51
INSTALL.md
Normal file
|
@ -0,0 +1,51 @@
|
|||
# Ubuntu 13.10 x64
|
||||
|
||||
## Capistrano setup
|
||||
|
||||
SSH as root, and install the basics
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade
|
||||
|
||||
Create a deploy user. Disable password authentication and add it to the www-data group.
|
||||
|
||||
sudo adduser deploy
|
||||
sudo passwd -l deploy
|
||||
sudo usermod -a -G www-data deploy
|
||||
|
||||
Add the following to `/etc/sudoers` to allow the `deploy` user to manage nginx and foreman via sudo without a password
|
||||
|
||||
# /etc/sudoers
|
||||
Cmnd_Alias START_FOREMAN = /sbin/start foreman
|
||||
|
||||
deploy ALL=NOPASSWD:START_FOREMAN
|
||||
deploy ALL=NOPASSWD:/etc/init.d/nginx
|
||||
|
||||
## Install rbenv, ruby and bundler
|
||||
|
||||
As root, install dependencies
|
||||
|
||||
sudo apt-get install nginx git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libmysql-ruby libmysqlclient-dev
|
||||
|
||||
Switch user to deploy, and install rbenv
|
||||
|
||||
su deploy
|
||||
cd ~
|
||||
git clone git://github.com/sstephenson/rbenv.git .rbenv
|
||||
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
|
||||
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
|
||||
exec $SHELL
|
||||
|
||||
git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
|
||||
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
|
||||
exec $SHELL
|
||||
|
||||
rbenv install 2.1.1
|
||||
rbenv global 2.1.1
|
||||
|
||||
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
|
||||
gem install bundler
|
||||
|
||||
## Install the ENSL site
|
||||
|
||||
mkdir /var/www/virtual/ensl.org/deploy
|
1
LICENSE.md
Normal file
1
LICENSE.md
Normal file
|
@ -0,0 +1 @@
|
|||
Copyright 2014 ENSL.org
|
1
Procfile
Normal file
1
Procfile
Normal file
|
@ -0,0 +1 @@
|
|||
web: bundle exec unicorn -p $UNICORN_PORT -l $UNICORN_SOCKET -c ./config/unicorn.rb
|
33
README.md
Normal file
33
README.md
Normal file
|
@ -0,0 +1,33 @@
|
|||
# ENSL Website
|
||||
|
||||
This is the source code of ENSL website. Currently deployed on [European NS League](http://www.ensl.org).
|
||||
|
||||
Features:
|
||||
|
||||
- Articles
|
||||
- Commenting feature for most objects
|
||||
- Movie database
|
||||
- File database
|
||||
- ENSL Plugin API
|
||||
- Forums, usual forum features and ACL
|
||||
- Contest management
|
||||
- Teams and team member management
|
||||
- Brackets
|
||||
- Tournaments
|
||||
- Match database
|
||||
- Challenging system
|
||||
- Instant webchat (shoutbox)
|
||||
- Private messages
|
||||
- Issue management
|
||||
- Very popular AJAX-based pick-up system
|
||||
- Map database
|
||||
- Votable polls
|
||||
- Twitter feed
|
||||
- Server database and RCON interface
|
||||
- Log file parsing (partially complete)
|
||||
|
||||
## Contributors
|
||||
|
||||
- [Ari Timonen](https://github.com/jirikivaari) - Original author
|
||||
- [Florent Latombe](https://github.com/flatombe) - Improvements
|
||||
- [Luke Barratt](https://github.com/lbarratt) - Improvements
|
13
Rakefile
Normal file
13
Rakefile
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||
|
||||
|
||||
|
||||
require File.expand_path('../config/application', __FILE__)
|
||||
|
||||
require 'rake/dsl_definition'
|
||||
require 'rake'
|
||||
require 'rake/testtask'
|
||||
require 'rake/task'
|
||||
|
||||
Ensl::Application.load_tasks
|
15
app/assets/javascripts/application.js
Normal file
15
app/assets/javascripts/application.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
// This is a manifest file that'll be compiled into including all the files listed below.
|
||||
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
||||
// be included in the compiled file accessible from http://example.com/assets/application.js
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||
// the compiled file.
|
||||
//
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require jquery.periodicalupdater
|
||||
//= require jquery.jplayer.min
|
||||
//= require flowplayer
|
||||
//= require tinymce-jquery
|
||||
//= require yetii
|
||||
//= require local
|
||||
|
24
app/assets/javascripts/flowplayer.js
Normal file
24
app/assets/javascripts/flowplayer.js
Normal file
File diff suppressed because one or more lines are too long
97
app/assets/javascripts/jquery.jplayer.min.js
vendored
Normal file
97
app/assets/javascripts/jquery.jplayer.min.js
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* jPlayer Plugin for jQuery JavaScript Library
|
||||
* http://www.jplayer.org
|
||||
*
|
||||
* Copyright (c) 2009 - 2011 Happyworm Ltd
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* - http://www.opensource.org/licenses/mit-license.php
|
||||
* - http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* Author: Mark J Panaghiston
|
||||
* Version: 2.1.0
|
||||
* Date: 1st September 2011
|
||||
*/
|
||||
|
||||
(function(b,f){b.fn.jPlayer=function(a){var c=typeof a==="string",d=Array.prototype.slice.call(arguments,1),e=this,a=!c&&d.length?b.extend.apply(null,[!0,a].concat(d)):a;if(c&&a.charAt(0)==="_")return e;c?this.each(function(){var c=b.data(this,"jPlayer"),h=c&&b.isFunction(c[a])?c[a].apply(c,d):c;if(h!==c&&h!==f)return e=h,!1}):this.each(function(){var c=b.data(this,"jPlayer");c?c.option(a||{}):b.data(this,"jPlayer",new b.jPlayer(a,this))});return e};b.jPlayer=function(a,c){if(arguments.length){this.element=
|
||||
b(c);this.options=b.extend(!0,{},this.options,a);var d=this;this.element.bind("remove.jPlayer",function(){d.destroy()});this._init()}};b.jPlayer.emulateMethods="load play pause";b.jPlayer.emulateStatus="src readyState networkState currentTime duration paused ended playbackRate";b.jPlayer.emulateOptions="muted volume";b.jPlayer.reservedEvent="ready flashreset resize repeat error warning";b.jPlayer.event={ready:"jPlayer_ready",flashreset:"jPlayer_flashreset",resize:"jPlayer_resize",repeat:"jPlayer_repeat",
|
||||
click:"jPlayer_click",error:"jPlayer_error",warning:"jPlayer_warning",loadstart:"jPlayer_loadstart",progress:"jPlayer_progress",suspend:"jPlayer_suspend",abort:"jPlayer_abort",emptied:"jPlayer_emptied",stalled:"jPlayer_stalled",play:"jPlayer_play",pause:"jPlayer_pause",loadedmetadata:"jPlayer_loadedmetadata",loadeddata:"jPlayer_loadeddata",waiting:"jPlayer_waiting",playing:"jPlayer_playing",canplay:"jPlayer_canplay",canplaythrough:"jPlayer_canplaythrough",seeking:"jPlayer_seeking",seeked:"jPlayer_seeked",
|
||||
timeupdate:"jPlayer_timeupdate",ended:"jPlayer_ended",ratechange:"jPlayer_ratechange",durationchange:"jPlayer_durationchange",volumechange:"jPlayer_volumechange"};b.jPlayer.htmlEvent="loadstart,abort,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,ratechange".split(",");b.jPlayer.pause=function(){b.each(b.jPlayer.prototype.instances,function(a,b){b.data("jPlayer").status.srcSet&&b.jPlayer("pause")})};b.jPlayer.timeFormat={showHour:!1,showMin:!0,showSec:!0,padHour:!1,padMin:!0,padSec:!0,
|
||||
sepHour:":",sepMin:":",sepSec:""};b.jPlayer.convertTime=function(a){var c=new Date(a*1E3),d=c.getUTCHours(),a=c.getUTCMinutes(),c=c.getUTCSeconds(),d=b.jPlayer.timeFormat.padHour&&d<10?"0"+d:d,a=b.jPlayer.timeFormat.padMin&&a<10?"0"+a:a,c=b.jPlayer.timeFormat.padSec&&c<10?"0"+c:c;return(b.jPlayer.timeFormat.showHour?d+b.jPlayer.timeFormat.sepHour:"")+(b.jPlayer.timeFormat.showMin?a+b.jPlayer.timeFormat.sepMin:"")+(b.jPlayer.timeFormat.showSec?c+b.jPlayer.timeFormat.sepSec:"")};b.jPlayer.uaBrowser=
|
||||
function(a){var a=a.toLowerCase(),b=/(opera)(?:.*version)?[ \/]([\w.]+)/,d=/(msie) ([\w.]+)/,e=/(mozilla)(?:.*? rv:([\w.]+))?/,a=/(webkit)[ \/]([\w.]+)/.exec(a)||b.exec(a)||d.exec(a)||a.indexOf("compatible")<0&&e.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}};b.jPlayer.uaPlatform=function(a){var b=a.toLowerCase(),d=/(android)/,e=/(mobile)/,a=/(ipad|iphone|ipod|android|blackberry|playbook|windows ce|webos)/.exec(b)||[],b=/(ipad|playbook)/.exec(b)||!e.exec(b)&&d.exec(b)||[];a[1]&&(a[1]=a[1].replace(/\s/g,
|
||||
"_"));return{platform:a[1]||"",tablet:b[1]||""}};b.jPlayer.browser={};b.jPlayer.platform={};var i=b.jPlayer.uaBrowser(navigator.userAgent);if(i.browser)b.jPlayer.browser[i.browser]=!0,b.jPlayer.browser.version=i.version;i=b.jPlayer.uaPlatform(navigator.userAgent);if(i.platform)b.jPlayer.platform[i.platform]=!0,b.jPlayer.platform.mobile=!i.tablet,b.jPlayer.platform.tablet=!!i.tablet;b.jPlayer.prototype={count:0,version:{script:"2.1.0",needFlash:"2.1.0",flash:"unknown"},options:{swfPath:"js",solution:"html, flash",
|
||||
supplied:"mp3",preload:"metadata",volume:0.8,muted:!1,wmode:"opaque",backgroundColor:"#000000",cssSelectorAncestor:"#jp_container_1",cssSelector:{videoPlay:".jp-video-play",play:".jp-play",pause:".jp-pause",stop:".jp-stop",seekBar:".jp-seek-bar",playBar:".jp-play-bar",mute:".jp-mute",unmute:".jp-unmute",volumeBar:".jp-volume-bar",volumeBarValue:".jp-volume-bar-value",volumeMax:".jp-volume-max",currentTime:".jp-current-time",duration:".jp-duration",fullScreen:".jp-full-screen",restoreScreen:".jp-restore-screen",
|
||||
repeat:".jp-repeat",repeatOff:".jp-repeat-off",gui:".jp-gui",noSolution:".jp-no-solution"},fullScreen:!1,autohide:{restored:!1,full:!0,fadeIn:200,fadeOut:600,hold:1E3},loop:!1,repeat:function(a){a.jPlayer.options.loop?b(this).unbind(".jPlayerRepeat").bind(b.jPlayer.event.ended+".jPlayer.jPlayerRepeat",function(){b(this).jPlayer("play")}):b(this).unbind(".jPlayerRepeat")},nativeVideoControls:{},noFullScreen:{msie:/msie [0-6]/,ipad:/ipad.*?os [0-4]/,iphone:/iphone/,ipod:/ipod/,android_pad:/android [0-3](?!.*?mobile)/,
|
||||
android_phone:/android.*?mobile/,blackberry:/blackberry/,windows_ce:/windows ce/,webos:/webos/},noVolume:{ipad:/ipad/,iphone:/iphone/,ipod:/ipod/,android_pad:/android(?!.*?mobile)/,android_phone:/android.*?mobile/,blackberry:/blackberry/,windows_ce:/windows ce/,webos:/webos/,playbook:/playbook/},verticalVolume:!1,idPrefix:"jp",noConflict:"jQuery",emulateHtml:!1,errorAlerts:!1,warningAlerts:!1},optionsAudio:{size:{width:"0px",height:"0px",cssClass:""},sizeFull:{width:"0px",height:"0px",cssClass:""}},
|
||||
optionsVideo:{size:{width:"480px",height:"270px",cssClass:"jp-video-270p"},sizeFull:{width:"100%",height:"100%",cssClass:"jp-video-full"}},instances:{},status:{src:"",media:{},paused:!0,format:{},formatType:"",waitForPlay:!0,waitForLoad:!0,srcSet:!1,video:!1,seekPercent:0,currentPercentRelative:0,currentPercentAbsolute:0,currentTime:0,duration:0,readyState:0,networkState:0,playbackRate:1,ended:0},internal:{ready:!1},solution:{html:!0,flash:!0},format:{mp3:{codec:'audio/mpeg; codecs="mp3"',flashCanPlay:!0,
|
||||
media:"audio"},m4a:{codec:'audio/mp4; codecs="mp4a.40.2"',flashCanPlay:!0,media:"audio"},oga:{codec:'audio/ogg; codecs="vorbis"',flashCanPlay:!1,media:"audio"},wav:{codec:'audio/wav; codecs="1"',flashCanPlay:!1,media:"audio"},webma:{codec:'audio/webm; codecs="vorbis"',flashCanPlay:!1,media:"audio"},fla:{codec:"audio/x-flv",flashCanPlay:!0,media:"audio"},m4v:{codec:'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',flashCanPlay:!0,media:"video"},ogv:{codec:'video/ogg; codecs="theora, vorbis"',flashCanPlay:!1,
|
||||
media:"video"},webmv:{codec:'video/webm; codecs="vorbis, vp8"',flashCanPlay:!1,media:"video"},flv:{codec:"video/x-flv",flashCanPlay:!0,media:"video"}},_init:function(){var a=this;this.element.empty();this.status=b.extend({},this.status);this.internal=b.extend({},this.internal);this.internal.domNode=this.element.get(0);this.formats=[];this.solutions=[];this.require={};this.htmlElement={};this.html={};this.html.audio={};this.html.video={};this.flash={};this.css={};this.css.cs={};this.css.jq={};this.ancestorJq=
|
||||
[];this.options.volume=this._limitValue(this.options.volume,0,1);b.each(this.options.supplied.toLowerCase().split(","),function(c,d){var e=d.replace(/^\s+|\s+$/g,"");if(a.format[e]){var f=!1;b.each(a.formats,function(a,b){if(e===b)return f=!0,!1});f||a.formats.push(e)}});b.each(this.options.solution.toLowerCase().split(","),function(c,d){var e=d.replace(/^\s+|\s+$/g,"");if(a.solution[e]){var f=!1;b.each(a.solutions,function(a,b){if(e===b)return f=!0,!1});f||a.solutions.push(e)}});this.internal.instance=
|
||||
"jp_"+this.count;this.instances[this.internal.instance]=this.element;this.element.attr("id")||this.element.attr("id",this.options.idPrefix+"_jplayer_"+this.count);this.internal.self=b.extend({},{id:this.element.attr("id"),jq:this.element});this.internal.audio=b.extend({},{id:this.options.idPrefix+"_audio_"+this.count,jq:f});this.internal.video=b.extend({},{id:this.options.idPrefix+"_video_"+this.count,jq:f});this.internal.flash=b.extend({},{id:this.options.idPrefix+"_flash_"+this.count,jq:f,swf:this.options.swfPath+
|
||||
(this.options.swfPath.toLowerCase().slice(-4)!==".swf"?(this.options.swfPath&&this.options.swfPath.slice(-1)!=="/"?"/":"")+"Jplayer.swf":"")});this.internal.poster=b.extend({},{id:this.options.idPrefix+"_poster_"+this.count,jq:f});b.each(b.jPlayer.event,function(b,c){a.options[b]!==f&&(a.element.bind(c+".jPlayer",a.options[b]),a.options[b]=f)});this.require.audio=!1;this.require.video=!1;b.each(this.formats,function(b,c){a.require[a.format[c].media]=!0});this.options=this.require.video?b.extend(!0,
|
||||
{},this.optionsVideo,this.options):b.extend(!0,{},this.optionsAudio,this.options);this._setSize();this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this.status.noFullScreen=this._uaBlocklist(this.options.noFullScreen);this.status.noVolume=this._uaBlocklist(this.options.noVolume);this._restrictNativeVideoControls();this.htmlElement.poster=document.createElement("img");this.htmlElement.poster.id=this.internal.poster.id;this.htmlElement.poster.onload=function(){(!a.status.video||
|
||||
a.status.waitForPlay)&&a.internal.poster.jq.show()};this.element.append(this.htmlElement.poster);this.internal.poster.jq=b("#"+this.internal.poster.id);this.internal.poster.jq.css({width:this.status.width,height:this.status.height});this.internal.poster.jq.hide();this.internal.poster.jq.bind("click.jPlayer",function(){a._trigger(b.jPlayer.event.click)});this.html.audio.available=!1;if(this.require.audio)this.htmlElement.audio=document.createElement("audio"),this.htmlElement.audio.id=this.internal.audio.id,
|
||||
this.html.audio.available=!!this.htmlElement.audio.canPlayType&&this._testCanPlayType(this.htmlElement.audio);this.html.video.available=!1;if(this.require.video)this.htmlElement.video=document.createElement("video"),this.htmlElement.video.id=this.internal.video.id,this.html.video.available=!!this.htmlElement.video.canPlayType&&this._testCanPlayType(this.htmlElement.video);this.flash.available=this._checkForFlash(10);this.html.canPlay={};this.flash.canPlay={};b.each(this.formats,function(b,c){a.html.canPlay[c]=
|
||||
a.html[a.format[c].media].available&&""!==a.htmlElement[a.format[c].media].canPlayType(a.format[c].codec);a.flash.canPlay[c]=a.format[c].flashCanPlay&&a.flash.available});this.html.desired=!1;this.flash.desired=!1;b.each(this.solutions,function(c,d){if(c===0)a[d].desired=!0;else{var e=!1,f=!1;b.each(a.formats,function(b,c){a[a.solutions[0]].canPlay[c]&&(a.format[c].media==="video"?f=!0:e=!0)});a[d].desired=a.require.audio&&!e||a.require.video&&!f}});this.html.support={};this.flash.support={};b.each(this.formats,
|
||||
function(b,c){a.html.support[c]=a.html.canPlay[c]&&a.html.desired;a.flash.support[c]=a.flash.canPlay[c]&&a.flash.desired});this.html.used=!1;this.flash.used=!1;b.each(this.solutions,function(c,d){b.each(a.formats,function(b,c){if(a[d].support[c])return a[d].used=!0,!1})});this._resetActive();this._resetGate();this._cssSelectorAncestor(this.options.cssSelectorAncestor);!this.html.used&&!this.flash.used?(this._error({type:b.jPlayer.error.NO_SOLUTION,context:"{solution:'"+this.options.solution+"', supplied:'"+
|
||||
this.options.supplied+"'}",message:b.jPlayer.errorMsg.NO_SOLUTION,hint:b.jPlayer.errorHint.NO_SOLUTION}),this.css.jq.noSolution.length&&this.css.jq.noSolution.show()):this.css.jq.noSolution.length&&this.css.jq.noSolution.hide();if(this.flash.used){var c,d="jQuery="+encodeURI(this.options.noConflict)+"&id="+encodeURI(this.internal.self.id)+"&vol="+this.options.volume+"&muted="+this.options.muted;if(b.browser.msie&&Number(b.browser.version)<=8){d=['<param name="movie" value="'+this.internal.flash.swf+
|
||||
'" />','<param name="FlashVars" value="'+d+'" />','<param name="allowScriptAccess" value="always" />','<param name="bgcolor" value="'+this.options.backgroundColor+'" />','<param name="wmode" value="'+this.options.wmode+'" />'];c=document.createElement('<object id="'+this.internal.flash.id+'" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="0" height="0"></object>');for(var e=0;e<d.length;e++)c.appendChild(document.createElement(d[e]))}else e=function(a,b,c){var d=document.createElement("param");
|
||||
d.setAttribute("name",b);d.setAttribute("value",c);a.appendChild(d)},c=document.createElement("object"),c.setAttribute("id",this.internal.flash.id),c.setAttribute("data",this.internal.flash.swf),c.setAttribute("type","application/x-shockwave-flash"),c.setAttribute("width","1"),c.setAttribute("height","1"),e(c,"flashvars",d),e(c,"allowscriptaccess","always"),e(c,"bgcolor",this.options.backgroundColor),e(c,"wmode",this.options.wmode);this.element.append(c);this.internal.flash.jq=b(c)}if(this.html.used){if(this.html.audio.available)this._addHtmlEventListeners(this.htmlElement.audio,
|
||||
this.html.audio),this.element.append(this.htmlElement.audio),this.internal.audio.jq=b("#"+this.internal.audio.id);if(this.html.video.available)this._addHtmlEventListeners(this.htmlElement.video,this.html.video),this.element.append(this.htmlElement.video),this.internal.video.jq=b("#"+this.internal.video.id),this.status.nativeVideoControls?this.internal.video.jq.css({width:this.status.width,height:this.status.height}):this.internal.video.jq.css({width:"0px",height:"0px"}),this.internal.video.jq.bind("click.jPlayer",
|
||||
function(){a._trigger(b.jPlayer.event.click)})}this.options.emulateHtml&&this._emulateHtmlBridge();this.html.used&&!this.flash.used&&setTimeout(function(){a.internal.ready=!0;a.version.flash="n/a";a._trigger(b.jPlayer.event.repeat);a._trigger(b.jPlayer.event.ready)},100);this._updateNativeVideoControls();this._updateInterface();this._updateButtons(!1);this._updateAutohide();this._updateVolume(this.options.volume);this._updateMute(this.options.muted);this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide();
|
||||
b.jPlayer.prototype.count++},destroy:function(){this.clearMedia();this._removeUiClass();this.css.jq.currentTime.length&&this.css.jq.currentTime.text("");this.css.jq.duration.length&&this.css.jq.duration.text("");b.each(this.css.jq,function(a,b){b.length&&b.unbind(".jPlayer")});this.internal.poster.jq.unbind(".jPlayer");this.internal.video.jq&&this.internal.video.jq.unbind(".jPlayer");this.options.emulateHtml&&this._destroyHtmlBridge();this.element.removeData("jPlayer");this.element.unbind(".jPlayer");
|
||||
this.element.empty();delete this.instances[this.internal.instance]},enable:function(){},disable:function(){},_testCanPlayType:function(a){try{return a.canPlayType(this.format.mp3.codec),!0}catch(b){return!1}},_uaBlocklist:function(a){var c=navigator.userAgent.toLowerCase(),d=!1;b.each(a,function(a,b){if(b&&b.test(c))return d=!0,!1});return d},_restrictNativeVideoControls:function(){if(this.require.audio&&this.status.nativeVideoControls)this.status.nativeVideoControls=!1,this.status.noFullScreen=!0},
|
||||
_updateNativeVideoControls:function(){if(this.html.video.available&&this.html.used)this.htmlElement.video.controls=this.status.nativeVideoControls,this._updateAutohide(),this.status.nativeVideoControls&&this.require.video?(this.internal.poster.jq.hide(),this.internal.video.jq.css({width:this.status.width,height:this.status.height})):this.status.waitForPlay&&this.status.video&&(this.internal.poster.jq.show(),this.internal.video.jq.css({width:"0px",height:"0px"}))},_addHtmlEventListeners:function(a,
|
||||
c){var d=this;a.preload=this.options.preload;a.muted=this.options.muted;a.volume=this.options.volume;a.addEventListener("progress",function(){c.gate&&(d._getHtmlStatus(a),d._updateInterface(),d._trigger(b.jPlayer.event.progress))},!1);a.addEventListener("timeupdate",function(){c.gate&&(d._getHtmlStatus(a),d._updateInterface(),d._trigger(b.jPlayer.event.timeupdate))},!1);a.addEventListener("durationchange",function(){if(c.gate)d.status.duration=this.duration,d._getHtmlStatus(a),d._updateInterface(),
|
||||
d._trigger(b.jPlayer.event.durationchange)},!1);a.addEventListener("play",function(){c.gate&&(d._updateButtons(!0),d._html_checkWaitForPlay(),d._trigger(b.jPlayer.event.play))},!1);a.addEventListener("playing",function(){c.gate&&(d._updateButtons(!0),d._seeked(),d._trigger(b.jPlayer.event.playing))},!1);a.addEventListener("pause",function(){c.gate&&(d._updateButtons(!1),d._trigger(b.jPlayer.event.pause))},!1);a.addEventListener("waiting",function(){c.gate&&(d._seeking(),d._trigger(b.jPlayer.event.waiting))},
|
||||
!1);a.addEventListener("seeking",function(){c.gate&&(d._seeking(),d._trigger(b.jPlayer.event.seeking))},!1);a.addEventListener("seeked",function(){c.gate&&(d._seeked(),d._trigger(b.jPlayer.event.seeked))},!1);a.addEventListener("volumechange",function(){if(c.gate)d.options.volume=a.volume,d.options.muted=a.muted,d._updateMute(),d._updateVolume(),d._trigger(b.jPlayer.event.volumechange)},!1);a.addEventListener("suspend",function(){c.gate&&(d._seeked(),d._trigger(b.jPlayer.event.suspend))},!1);a.addEventListener("ended",
|
||||
function(){if(c.gate){if(!b.jPlayer.browser.webkit)d.htmlElement.media.currentTime=0;d.htmlElement.media.pause();d._updateButtons(!1);d._getHtmlStatus(a,!0);d._updateInterface();d._trigger(b.jPlayer.event.ended)}},!1);a.addEventListener("error",function(){if(c.gate&&(d._updateButtons(!1),d._seeked(),d.status.srcSet))clearTimeout(d.internal.htmlDlyCmdId),d.status.waitForLoad=!0,d.status.waitForPlay=!0,d.status.video&&!d.status.nativeVideoControls&&d.internal.video.jq.css({width:"0px",height:"0px"}),
|
||||
d._validString(d.status.media.poster)&&!d.status.nativeVideoControls&&d.internal.poster.jq.show(),d.css.jq.videoPlay.length&&d.css.jq.videoPlay.show(),d._error({type:b.jPlayer.error.URL,context:d.status.src,message:b.jPlayer.errorMsg.URL,hint:b.jPlayer.errorHint.URL})},!1);b.each(b.jPlayer.htmlEvent,function(e,g){a.addEventListener(this,function(){c.gate&&d._trigger(b.jPlayer.event[g])},!1)})},_getHtmlStatus:function(a,b){var d=0,e=0,g=0,f=0;if(a.duration)this.status.duration=a.duration;d=a.currentTime;
|
||||
e=this.status.duration>0?100*d/this.status.duration:0;typeof a.seekable==="object"&&a.seekable.length>0?(g=this.status.duration>0?100*a.seekable.end(a.seekable.length-1)/this.status.duration:100,f=100*a.currentTime/a.seekable.end(a.seekable.length-1)):(g=100,f=e);b&&(e=f=d=0);this.status.seekPercent=g;this.status.currentPercentRelative=f;this.status.currentPercentAbsolute=e;this.status.currentTime=d;this.status.readyState=a.readyState;this.status.networkState=a.networkState;this.status.playbackRate=
|
||||
a.playbackRate;this.status.ended=a.ended},_resetStatus:function(){this.status=b.extend({},this.status,b.jPlayer.prototype.status)},_trigger:function(a,c,d){a=b.Event(a);a.jPlayer={};a.jPlayer.version=b.extend({},this.version);a.jPlayer.options=b.extend(!0,{},this.options);a.jPlayer.status=b.extend(!0,{},this.status);a.jPlayer.html=b.extend(!0,{},this.html);a.jPlayer.flash=b.extend(!0,{},this.flash);if(c)a.jPlayer.error=b.extend({},c);if(d)a.jPlayer.warning=b.extend({},d);this.element.trigger(a)},
|
||||
jPlayerFlashEvent:function(a,c){if(a===b.jPlayer.event.ready)if(this.internal.ready){if(this.flash.gate){if(this.status.srcSet){var d=this.status.currentTime,e=this.status.paused;this.setMedia(this.status.media);d>0&&(e?this.pause(d):this.play(d))}this._trigger(b.jPlayer.event.flashreset)}}else this.internal.ready=!0,this.internal.flash.jq.css({width:"0px",height:"0px"}),this.version.flash=c.version,this.version.needFlash!==this.version.flash&&this._error({type:b.jPlayer.error.VERSION,context:this.version.flash,
|
||||
message:b.jPlayer.errorMsg.VERSION+this.version.flash,hint:b.jPlayer.errorHint.VERSION}),this._trigger(b.jPlayer.event.repeat),this._trigger(a);if(this.flash.gate)switch(a){case b.jPlayer.event.progress:this._getFlashStatus(c);this._updateInterface();this._trigger(a);break;case b.jPlayer.event.timeupdate:this._getFlashStatus(c);this._updateInterface();this._trigger(a);break;case b.jPlayer.event.play:this._seeked();this._updateButtons(!0);this._trigger(a);break;case b.jPlayer.event.pause:this._updateButtons(!1);
|
||||
this._trigger(a);break;case b.jPlayer.event.ended:this._updateButtons(!1);this._trigger(a);break;case b.jPlayer.event.click:this._trigger(a);break;case b.jPlayer.event.error:this.status.waitForLoad=!0;this.status.waitForPlay=!0;this.status.video&&this.internal.flash.jq.css({width:"0px",height:"0px"});this._validString(this.status.media.poster)&&this.internal.poster.jq.show();this.css.jq.videoPlay.length&&this.status.video&&this.css.jq.videoPlay.show();this.status.video?this._flash_setVideo(this.status.media):
|
||||
this._flash_setAudio(this.status.media);this._updateButtons(!1);this._error({type:b.jPlayer.error.URL,context:c.src,message:b.jPlayer.errorMsg.URL,hint:b.jPlayer.errorHint.URL});break;case b.jPlayer.event.seeking:this._seeking();this._trigger(a);break;case b.jPlayer.event.seeked:this._seeked();this._trigger(a);break;case b.jPlayer.event.ready:break;default:this._trigger(a)}return!1},_getFlashStatus:function(a){this.status.seekPercent=a.seekPercent;this.status.currentPercentRelative=a.currentPercentRelative;
|
||||
this.status.currentPercentAbsolute=a.currentPercentAbsolute;this.status.currentTime=a.currentTime;this.status.duration=a.duration;this.status.readyState=4;this.status.networkState=0;this.status.playbackRate=1;this.status.ended=!1},_updateButtons:function(a){if(a!==f)this.status.paused=!a,this.css.jq.play.length&&this.css.jq.pause.length&&(a?(this.css.jq.play.hide(),this.css.jq.pause.show()):(this.css.jq.play.show(),this.css.jq.pause.hide()));this.css.jq.restoreScreen.length&&this.css.jq.fullScreen.length&&
|
||||
(this.status.noFullScreen?(this.css.jq.fullScreen.hide(),this.css.jq.restoreScreen.hide()):this.options.fullScreen?(this.css.jq.fullScreen.hide(),this.css.jq.restoreScreen.show()):(this.css.jq.fullScreen.show(),this.css.jq.restoreScreen.hide()));this.css.jq.repeat.length&&this.css.jq.repeatOff.length&&(this.options.loop?(this.css.jq.repeat.hide(),this.css.jq.repeatOff.show()):(this.css.jq.repeat.show(),this.css.jq.repeatOff.hide()))},_updateInterface:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.width(this.status.seekPercent+
|
||||
"%");this.css.jq.playBar.length&&this.css.jq.playBar.width(this.status.currentPercentRelative+"%");this.css.jq.currentTime.length&&this.css.jq.currentTime.text(b.jPlayer.convertTime(this.status.currentTime));this.css.jq.duration.length&&this.css.jq.duration.text(b.jPlayer.convertTime(this.status.duration))},_seeking:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.addClass("jp-seeking-bg")},_seeked:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.removeClass("jp-seeking-bg")},
|
||||
_resetGate:function(){this.html.audio.gate=!1;this.html.video.gate=!1;this.flash.gate=!1},_resetActive:function(){this.html.active=!1;this.flash.active=!1},setMedia:function(a){var c=this,d=!1,e=this.status.media.poster!==a.poster;this._resetMedia();this._resetGate();this._resetActive();b.each(this.formats,function(e,f){var i=c.format[f].media==="video";b.each(c.solutions,function(b,e){if(c[e].support[f]&&c._validString(a[f])){var g=e==="html";i?(g?(c.html.video.gate=!0,c._html_setVideo(a),c.html.active=
|
||||
!0):(c.flash.gate=!0,c._flash_setVideo(a),c.flash.active=!0),c.css.jq.videoPlay.length&&c.css.jq.videoPlay.show(),c.status.video=!0):(g?(c.html.audio.gate=!0,c._html_setAudio(a),c.html.active=!0):(c.flash.gate=!0,c._flash_setAudio(a),c.flash.active=!0),c.css.jq.videoPlay.length&&c.css.jq.videoPlay.hide(),c.status.video=!1);d=!0;return!1}});if(d)return!1});if(d){if((!this.status.nativeVideoControls||!this.html.video.gate)&&this._validString(a.poster))e?this.htmlElement.poster.src=a.poster:this.internal.poster.jq.show();
|
||||
this.status.srcSet=!0;this.status.media=b.extend({},a);this._updateButtons(!1);this._updateInterface()}else this._error({type:b.jPlayer.error.NO_SUPPORT,context:"{supplied:'"+this.options.supplied+"'}",message:b.jPlayer.errorMsg.NO_SUPPORT,hint:b.jPlayer.errorHint.NO_SUPPORT})},_resetMedia:function(){this._resetStatus();this._updateButtons(!1);this._updateInterface();this._seeked();this.internal.poster.jq.hide();clearTimeout(this.internal.htmlDlyCmdId);this.html.active?this._html_resetMedia():this.flash.active&&
|
||||
this._flash_resetMedia()},clearMedia:function(){this._resetMedia();this.html.active?this._html_clearMedia():this.flash.active&&this._flash_clearMedia();this._resetGate();this._resetActive()},load:function(){this.status.srcSet?this.html.active?this._html_load():this.flash.active&&this._flash_load():this._urlNotSetError("load")},play:function(a){a=typeof a==="number"?a:NaN;this.status.srcSet?this.html.active?this._html_play(a):this.flash.active&&this._flash_play(a):this._urlNotSetError("play")},videoPlay:function(){this.play()},
|
||||
pause:function(a){a=typeof a==="number"?a:NaN;this.status.srcSet?this.html.active?this._html_pause(a):this.flash.active&&this._flash_pause(a):this._urlNotSetError("pause")},pauseOthers:function(){var a=this;b.each(this.instances,function(b,d){a.element!==d&&d.data("jPlayer").status.srcSet&&d.jPlayer("pause")})},stop:function(){this.status.srcSet?this.html.active?this._html_pause(0):this.flash.active&&this._flash_pause(0):this._urlNotSetError("stop")},playHead:function(a){a=this._limitValue(a,0,100);
|
||||
this.status.srcSet?this.html.active?this._html_playHead(a):this.flash.active&&this._flash_playHead(a):this._urlNotSetError("playHead")},_muted:function(a){this.options.muted=a;this.html.used&&this._html_mute(a);this.flash.used&&this._flash_mute(a);!this.html.video.gate&&!this.html.audio.gate&&(this._updateMute(a),this._updateVolume(this.options.volume),this._trigger(b.jPlayer.event.volumechange))},mute:function(a){a=a===f?!0:!!a;this._muted(a)},unmute:function(a){a=a===f?!0:!!a;this._muted(!a)},_updateMute:function(a){if(a===
|
||||
f)a=this.options.muted;this.css.jq.mute.length&&this.css.jq.unmute.length&&(this.status.noVolume?(this.css.jq.mute.hide(),this.css.jq.unmute.hide()):a?(this.css.jq.mute.hide(),this.css.jq.unmute.show()):(this.css.jq.mute.show(),this.css.jq.unmute.hide()))},volume:function(a){a=this._limitValue(a,0,1);this.options.volume=a;this.html.used&&this._html_volume(a);this.flash.used&&this._flash_volume(a);!this.html.video.gate&&!this.html.audio.gate&&(this._updateVolume(a),this._trigger(b.jPlayer.event.volumechange))},
|
||||
volumeBar:function(a){if(this.css.jq.volumeBar.length){var b=this.css.jq.volumeBar.offset(),d=a.pageX-b.left,e=this.css.jq.volumeBar.width(),a=this.css.jq.volumeBar.height()-a.pageY+b.top,b=this.css.jq.volumeBar.height();this.options.verticalVolume?this.volume(a/b):this.volume(d/e)}this.options.muted&&this._muted(!1)},volumeBarValue:function(a){this.volumeBar(a)},_updateVolume:function(a){if(a===f)a=this.options.volume;a=this.options.muted?0:a;this.status.noVolume?(this.css.jq.volumeBar.length&&this.css.jq.volumeBar.hide(),
|
||||
this.css.jq.volumeBarValue.length&&this.css.jq.volumeBarValue.hide(),this.css.jq.volumeMax.length&&this.css.jq.volumeMax.hide()):(this.css.jq.volumeBar.length&&this.css.jq.volumeBar.show(),this.css.jq.volumeBarValue.length&&(this.css.jq.volumeBarValue.show(),this.css.jq.volumeBarValue[this.options.verticalVolume?"height":"width"](a*100+"%")),this.css.jq.volumeMax.length&&this.css.jq.volumeMax.show())},volumeMax:function(){this.volume(1);this.options.muted&&this._muted(!1)},_cssSelectorAncestor:function(a){var c=
|
||||
this;this.options.cssSelectorAncestor=a;this._removeUiClass();this.ancestorJq=a?b(a):[];a&&this.ancestorJq.length!==1&&this._warning({type:b.jPlayer.warning.CSS_SELECTOR_COUNT,context:a,message:b.jPlayer.warningMsg.CSS_SELECTOR_COUNT+this.ancestorJq.length+" found for cssSelectorAncestor.",hint:b.jPlayer.warningHint.CSS_SELECTOR_COUNT});this._addUiClass();b.each(this.options.cssSelector,function(a,b){c._cssSelector(a,b)})},_cssSelector:function(a,c){var d=this;typeof c==="string"?b.jPlayer.prototype.options.cssSelector[a]?
|
||||
(this.css.jq[a]&&this.css.jq[a].length&&this.css.jq[a].unbind(".jPlayer"),this.options.cssSelector[a]=c,this.css.cs[a]=this.options.cssSelectorAncestor+" "+c,this.css.jq[a]=c?b(this.css.cs[a]):[],this.css.jq[a].length&&this.css.jq[a].bind("click.jPlayer",function(c){d[a](c);b(this).blur();return!1}),c&&this.css.jq[a].length!==1&&this._warning({type:b.jPlayer.warning.CSS_SELECTOR_COUNT,context:this.css.cs[a],message:b.jPlayer.warningMsg.CSS_SELECTOR_COUNT+this.css.jq[a].length+" found for "+a+" method.",
|
||||
hint:b.jPlayer.warningHint.CSS_SELECTOR_COUNT})):this._warning({type:b.jPlayer.warning.CSS_SELECTOR_METHOD,context:a,message:b.jPlayer.warningMsg.CSS_SELECTOR_METHOD,hint:b.jPlayer.warningHint.CSS_SELECTOR_METHOD}):this._warning({type:b.jPlayer.warning.CSS_SELECTOR_STRING,context:c,message:b.jPlayer.warningMsg.CSS_SELECTOR_STRING,hint:b.jPlayer.warningHint.CSS_SELECTOR_STRING})},seekBar:function(a){if(this.css.jq.seekBar){var b=this.css.jq.seekBar.offset(),a=a.pageX-b.left,b=this.css.jq.seekBar.width();
|
||||
this.playHead(100*a/b)}},playBar:function(a){this.seekBar(a)},repeat:function(){this._loop(!0)},repeatOff:function(){this._loop(!1)},_loop:function(a){if(this.options.loop!==a)this.options.loop=a,this._updateButtons(),this._trigger(b.jPlayer.event.repeat)},currentTime:function(){},duration:function(){},gui:function(){},noSolution:function(){},option:function(a,c){var d=a;if(arguments.length===0)return b.extend(!0,{},this.options);if(typeof a==="string"){var e=a.split(".");if(c===f){for(var d=b.extend(!0,
|
||||
{},this.options),g=0;g<e.length;g++)if(d[e[g]]!==f)d=d[e[g]];else return this._warning({type:b.jPlayer.warning.OPTION_KEY,context:a,message:b.jPlayer.warningMsg.OPTION_KEY,hint:b.jPlayer.warningHint.OPTION_KEY}),f;return d}for(var g=d={},h=0;h<e.length;h++)h<e.length-1?(g[e[h]]={},g=g[e[h]]):g[e[h]]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(a,b){c._setOption(a,b)});return this},_setOption:function(a,c){var d=this;switch(a){case "volume":this.volume(c);
|
||||
break;case "muted":this._muted(c);break;case "cssSelectorAncestor":this._cssSelectorAncestor(c);break;case "cssSelector":b.each(c,function(a,b){d._cssSelector(a,b)});break;case "fullScreen":this.options[a]!==c&&(this._removeUiClass(),this.options[a]=c,this._refreshSize());break;case "size":!this.options.fullScreen&&this.options[a].cssClass!==c.cssClass&&this._removeUiClass();this.options[a]=b.extend({},this.options[a],c);this._refreshSize();break;case "sizeFull":this.options.fullScreen&&this.options[a].cssClass!==
|
||||
c.cssClass&&this._removeUiClass();this.options[a]=b.extend({},this.options[a],c);this._refreshSize();break;case "autohide":this.options[a]=b.extend({},this.options[a],c);this._updateAutohide();break;case "loop":this._loop(c);break;case "nativeVideoControls":this.options[a]=b.extend({},this.options[a],c);this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this._restrictNativeVideoControls();this._updateNativeVideoControls();break;case "noFullScreen":this.options[a]=
|
||||
b.extend({},this.options[a],c);this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this.status.noFullScreen=this._uaBlocklist(this.options.noFullScreen);this._restrictNativeVideoControls();this._updateButtons();break;case "noVolume":this.options[a]=b.extend({},this.options[a],c);this.status.noVolume=this._uaBlocklist(this.options.noVolume);this._updateVolume();this._updateMute();break;case "emulateHtml":this.options[a]!==c&&((this.options[a]=c)?this._emulateHtmlBridge():
|
||||
this._destroyHtmlBridge())}return this},_refreshSize:function(){this._setSize();this._addUiClass();this._updateSize();this._updateButtons();this._updateAutohide();this._trigger(b.jPlayer.event.resize)},_setSize:function(){this.options.fullScreen?(this.status.width=this.options.sizeFull.width,this.status.height=this.options.sizeFull.height,this.status.cssClass=this.options.sizeFull.cssClass):(this.status.width=this.options.size.width,this.status.height=this.options.size.height,this.status.cssClass=
|
||||
this.options.size.cssClass);this.element.css({width:this.status.width,height:this.status.height})},_addUiClass:function(){this.ancestorJq.length&&this.ancestorJq.addClass(this.status.cssClass)},_removeUiClass:function(){this.ancestorJq.length&&this.ancestorJq.removeClass(this.status.cssClass)},_updateSize:function(){this.internal.poster.jq.css({width:this.status.width,height:this.status.height});!this.status.waitForPlay&&this.html.active&&this.status.video||this.html.video.available&&this.html.used&&
|
||||
this.status.nativeVideoControls?this.internal.video.jq.css({width:this.status.width,height:this.status.height}):!this.status.waitForPlay&&this.flash.active&&this.status.video&&this.internal.flash.jq.css({width:this.status.width,height:this.status.height})},_updateAutohide:function(){var a=this,b=function(){a.css.jq.gui.fadeIn(a.options.autohide.fadeIn,function(){clearTimeout(a.internal.autohideId);a.internal.autohideId=setTimeout(function(){a.css.jq.gui.fadeOut(a.options.autohide.fadeOut)},a.options.autohide.hold)})};
|
||||
this.css.jq.gui.length&&(this.css.jq.gui.stop(!0,!0),clearTimeout(this.internal.autohideId),this.element.unbind(".jPlayerAutohide"),this.css.jq.gui.unbind(".jPlayerAutohide"),this.status.nativeVideoControls?this.css.jq.gui.hide():this.options.fullScreen&&this.options.autohide.full||!this.options.fullScreen&&this.options.autohide.restored?(this.element.bind("mousemove.jPlayer.jPlayerAutohide",b),this.css.jq.gui.bind("mousemove.jPlayer.jPlayerAutohide",b),this.css.jq.gui.hide()):this.css.jq.gui.show())},
|
||||
fullScreen:function(){this._setOption("fullScreen",!0)},restoreScreen:function(){this._setOption("fullScreen",!1)},_html_initMedia:function(){this.htmlElement.media.src=this.status.src;this.options.preload!=="none"&&this._html_load();this._trigger(b.jPlayer.event.timeupdate)},_html_setAudio:function(a){var c=this;b.each(this.formats,function(b,e){if(c.html.support[e]&&a[e])return c.status.src=a[e],c.status.format[e]=!0,c.status.formatType=e,!1});this.htmlElement.media=this.htmlElement.audio;this._html_initMedia()},
|
||||
_html_setVideo:function(a){var c=this;b.each(this.formats,function(b,e){if(c.html.support[e]&&a[e])return c.status.src=a[e],c.status.format[e]=!0,c.status.formatType=e,!1});if(this.status.nativeVideoControls)this.htmlElement.video.poster=this._validString(a.poster)?a.poster:"";this.htmlElement.media=this.htmlElement.video;this._html_initMedia()},_html_resetMedia:function(){this.htmlElement.media&&(this.htmlElement.media.id===this.internal.video.id&&!this.status.nativeVideoControls&&this.internal.video.jq.css({width:"0px",
|
||||
height:"0px"}),this.htmlElement.media.pause())},_html_clearMedia:function(){if(this.htmlElement.media)this.htmlElement.media.src="",this.htmlElement.media.load()},_html_load:function(){if(this.status.waitForLoad)this.status.waitForLoad=!1,this.htmlElement.media.load();clearTimeout(this.internal.htmlDlyCmdId)},_html_play:function(a){var b=this;this._html_load();this.htmlElement.media.play();if(!isNaN(a))try{this.htmlElement.media.currentTime=a}catch(d){this.internal.htmlDlyCmdId=setTimeout(function(){b.play(a)},
|
||||
100);return}this._html_checkWaitForPlay()},_html_pause:function(a){var b=this;a>0?this._html_load():clearTimeout(this.internal.htmlDlyCmdId);this.htmlElement.media.pause();if(!isNaN(a))try{this.htmlElement.media.currentTime=a}catch(d){this.internal.htmlDlyCmdId=setTimeout(function(){b.pause(a)},100);return}a>0&&this._html_checkWaitForPlay()},_html_playHead:function(a){var b=this;this._html_load();try{if(typeof this.htmlElement.media.seekable==="object"&&this.htmlElement.media.seekable.length>0)this.htmlElement.media.currentTime=
|
||||
a*this.htmlElement.media.seekable.end(this.htmlElement.media.seekable.length-1)/100;else if(this.htmlElement.media.duration>0&&!isNaN(this.htmlElement.media.duration))this.htmlElement.media.currentTime=a*this.htmlElement.media.duration/100;else throw"e";}catch(d){this.internal.htmlDlyCmdId=setTimeout(function(){b.playHead(a)},100);return}this.status.waitForLoad||this._html_checkWaitForPlay()},_html_checkWaitForPlay:function(){if(this.status.waitForPlay)this.status.waitForPlay=!1,this.css.jq.videoPlay.length&&
|
||||
this.css.jq.videoPlay.hide(),this.status.video&&(this.internal.poster.jq.hide(),this.internal.video.jq.css({width:this.status.width,height:this.status.height}))},_html_volume:function(a){if(this.html.audio.available)this.htmlElement.audio.volume=a;if(this.html.video.available)this.htmlElement.video.volume=a},_html_mute:function(a){if(this.html.audio.available)this.htmlElement.audio.muted=a;if(this.html.video.available)this.htmlElement.video.muted=a},_flash_setAudio:function(a){var c=this;try{if(b.each(this.formats,
|
||||
function(b,d){if(c.flash.support[d]&&a[d]){switch(d){case "m4a":case "fla":c._getMovie().fl_setAudio_m4a(a[d]);break;case "mp3":c._getMovie().fl_setAudio_mp3(a[d])}c.status.src=a[d];c.status.format[d]=!0;c.status.formatType=d;return!1}}),this.options.preload==="auto")this._flash_load(),this.status.waitForLoad=!1}catch(d){this._flashError(d)}},_flash_setVideo:function(a){var c=this;try{if(b.each(this.formats,function(b,d){if(c.flash.support[d]&&a[d]){switch(d){case "m4v":case "flv":c._getMovie().fl_setVideo_m4v(a[d])}c.status.src=
|
||||
a[d];c.status.format[d]=!0;c.status.formatType=d;return!1}}),this.options.preload==="auto")this._flash_load(),this.status.waitForLoad=!1}catch(d){this._flashError(d)}},_flash_resetMedia:function(){this.internal.flash.jq.css({width:"0px",height:"0px"});this._flash_pause(NaN)},_flash_clearMedia:function(){try{this._getMovie().fl_clearMedia()}catch(a){this._flashError(a)}},_flash_load:function(){try{this._getMovie().fl_load()}catch(a){this._flashError(a)}this.status.waitForLoad=!1},_flash_play:function(a){try{this._getMovie().fl_play(a)}catch(b){this._flashError(b)}this.status.waitForLoad=
|
||||
!1;this._flash_checkWaitForPlay()},_flash_pause:function(a){try{this._getMovie().fl_pause(a)}catch(b){this._flashError(b)}if(a>0)this.status.waitForLoad=!1,this._flash_checkWaitForPlay()},_flash_playHead:function(a){try{this._getMovie().fl_play_head(a)}catch(b){this._flashError(b)}this.status.waitForLoad||this._flash_checkWaitForPlay()},_flash_checkWaitForPlay:function(){if(this.status.waitForPlay)this.status.waitForPlay=!1,this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide(),this.status.video&&
|
||||
(this.internal.poster.jq.hide(),this.internal.flash.jq.css({width:this.status.width,height:this.status.height}))},_flash_volume:function(a){try{this._getMovie().fl_volume(a)}catch(b){this._flashError(b)}},_flash_mute:function(a){try{this._getMovie().fl_mute(a)}catch(b){this._flashError(b)}},_getMovie:function(){return document[this.internal.flash.id]},_checkForFlash:function(a){var b=!1,d;if(window.ActiveXObject)try{new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+a),b=!0}catch(e){}else navigator.plugins&&
|
||||
navigator.mimeTypes.length>0&&(d=navigator.plugins["Shockwave Flash"])&&navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/,"$1")>=a&&(b=!0);return b},_validString:function(a){return a&&typeof a==="string"},_limitValue:function(a,b,d){return a<b?b:a>d?d:a},_urlNotSetError:function(a){this._error({type:b.jPlayer.error.URL_NOT_SET,context:a,message:b.jPlayer.errorMsg.URL_NOT_SET,hint:b.jPlayer.errorHint.URL_NOT_SET})},_flashError:function(a){var c;c=this.internal.ready?"FLASH_DISABLED":
|
||||
"FLASH";this._error({type:b.jPlayer.error[c],context:this.internal.flash.swf,message:b.jPlayer.errorMsg[c]+a.message,hint:b.jPlayer.errorHint[c]});this.internal.flash.jq.css({width:"1px",height:"1px"})},_error:function(a){this._trigger(b.jPlayer.event.error,a);this.options.errorAlerts&&this._alert("Error!"+(a.message?"\n\n"+a.message:"")+(a.hint?"\n\n"+a.hint:"")+"\n\nContext: "+a.context)},_warning:function(a){this._trigger(b.jPlayer.event.warning,f,a);this.options.warningAlerts&&this._alert("Warning!"+
|
||||
(a.message?"\n\n"+a.message:"")+(a.hint?"\n\n"+a.hint:"")+"\n\nContext: "+a.context)},_alert:function(a){alert("jPlayer "+this.version.script+" : id='"+this.internal.self.id+"' : "+a)},_emulateHtmlBridge:function(){var a=this;b.each(b.jPlayer.emulateMethods.split(/\s+/g),function(b,d){a.internal.domNode[d]=function(b){a[d](b)}});b.each(b.jPlayer.event,function(c,d){var e=!0;b.each(b.jPlayer.reservedEvent.split(/\s+/g),function(a,b){if(b===c)return e=!1});e&&a.element.bind(d+".jPlayer.jPlayerHtml",
|
||||
function(){a._emulateHtmlUpdate();var b=document.createEvent("Event");b.initEvent(c,!1,!0);a.internal.domNode.dispatchEvent(b)})})},_emulateHtmlUpdate:function(){var a=this;b.each(b.jPlayer.emulateStatus.split(/\s+/g),function(b,d){a.internal.domNode[d]=a.status[d]});b.each(b.jPlayer.emulateOptions.split(/\s+/g),function(b,d){a.internal.domNode[d]=a.options[d]})},_destroyHtmlBridge:function(){var a=this;this.element.unbind(".jPlayerHtml");b.each((b.jPlayer.emulateMethods+" "+b.jPlayer.emulateStatus+
|
||||
" "+b.jPlayer.emulateOptions).split(/\s+/g),function(b,d){delete a.internal.domNode[d]})}};b.jPlayer.error={FLASH:"e_flash",FLASH_DISABLED:"e_flash_disabled",NO_SOLUTION:"e_no_solution",NO_SUPPORT:"e_no_support",URL:"e_url",URL_NOT_SET:"e_url_not_set",VERSION:"e_version"};b.jPlayer.errorMsg={FLASH:"jPlayer's Flash fallback is not configured correctly, or a command was issued before the jPlayer Ready event. Details: ",FLASH_DISABLED:"jPlayer's Flash fallback has been disabled by the browser due to the CSS rules you have used. Details: ",
|
||||
NO_SOLUTION:"No solution can be found by jPlayer in this browser. Neither HTML nor Flash can be used.",NO_SUPPORT:"It is not possible to play any media format provided in setMedia() on this browser using your current options.",URL:"Media URL could not be loaded.",URL_NOT_SET:"Attempt to issue media playback commands, while no media url is set.",VERSION:"jPlayer "+b.jPlayer.prototype.version.script+" needs Jplayer.swf version "+b.jPlayer.prototype.version.needFlash+" but found "};b.jPlayer.errorHint=
|
||||
{FLASH:"Check your swfPath option and that Jplayer.swf is there.",FLASH_DISABLED:"Check that you have not display:none; the jPlayer entity or any ancestor.",NO_SOLUTION:"Review the jPlayer options: support and supplied.",NO_SUPPORT:"Video or audio formats defined in the supplied option are missing.",URL:"Check media URL is valid.",URL_NOT_SET:"Use setMedia() to set the media URL.",VERSION:"Update jPlayer files."};b.jPlayer.warning={CSS_SELECTOR_COUNT:"e_css_selector_count",CSS_SELECTOR_METHOD:"e_css_selector_method",
|
||||
CSS_SELECTOR_STRING:"e_css_selector_string",OPTION_KEY:"e_option_key"};b.jPlayer.warningMsg={CSS_SELECTOR_COUNT:"The number of css selectors found did not equal one: ",CSS_SELECTOR_METHOD:"The methodName given in jPlayer('cssSelector') is not a valid jPlayer method.",CSS_SELECTOR_STRING:"The methodCssSelector given in jPlayer('cssSelector') is not a String or is empty.",OPTION_KEY:"The option requested in jPlayer('option') is undefined."};b.jPlayer.warningHint={CSS_SELECTOR_COUNT:"Check your css selector and the ancestor.",
|
||||
CSS_SELECTOR_METHOD:"Check your method name.",CSS_SELECTOR_STRING:"Check your css selector is a string.",OPTION_KEY:"Check your option name."}})(jQuery);
|
175
app/assets/javascripts/jquery.periodicalupdater.js
Normal file
175
app/assets/javascripts/jquery.periodicalupdater.js
Normal file
|
@ -0,0 +1,175 @@
|
|||
/**
|
||||
* PeriodicalUpdater - jQuery plugin for timed, decaying ajax calls
|
||||
*
|
||||
* http://www.360innovate.co.uk/blog/2009/03/periodicalupdater-for-jquery/
|
||||
* http://enfranchisedmind.com/blog/posts/jquery-periodicalupdater-ajax-polling/
|
||||
*
|
||||
* Copyright (c) 2009 by the following:
|
||||
* Frank White (http://customcode.info)
|
||||
* Robert Fischer (http://smokejumperit.com)
|
||||
* 360innovate (http://www.360innovate.co.uk)
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
var pu_log = function(msg) {
|
||||
try {
|
||||
console.log(msg);
|
||||
} catch(err) {}
|
||||
}
|
||||
|
||||
// Now back to our regularly scheduled work
|
||||
$.PeriodicalUpdater = function(url, options, callback, autoStopCallback){
|
||||
var settings = jQuery.extend(true, {
|
||||
url: url, // URL of ajax request
|
||||
cache: false, // By default, don't allow caching
|
||||
method: 'GET', // method; get or post
|
||||
data: '', // array of values to be passed to the page - e.g. {name: "John", greeting: "hello"}
|
||||
minTimeout: 1000, // starting value for the timeout in milliseconds
|
||||
maxTimeout: 8000, // maximum length of time between requests
|
||||
multiplier: 2, // if set to 2, timerInterval will double each time the response hasn't changed (up to maxTimeout)
|
||||
maxCalls: 0, // maximum number of calls. 0 = no limit.
|
||||
autoStop: 0 // automatically stop requests after this many returns of the same data. 0 = disabled
|
||||
}, options);
|
||||
|
||||
// set some initial values, then begin
|
||||
var timer = null;
|
||||
var timerInterval = settings.minTimeout;
|
||||
var maxCalls = settings.maxCalls;
|
||||
var autoStop = settings.autoStop;
|
||||
var calls = 0;
|
||||
var noChange = 0;
|
||||
var originalMaxCalls = maxCalls;
|
||||
|
||||
var reset_timer = function(interval) {
|
||||
if (timer != null) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
timerInterval = interval;
|
||||
pu_log('resetting timer to '+ timerInterval +'.');
|
||||
timer = setTimeout(getdata, timerInterval);
|
||||
}
|
||||
|
||||
// Function to boost the timer
|
||||
var boostPeriod = function() {
|
||||
if(settings.multiplier >= 1) {
|
||||
before = timerInterval;
|
||||
timerInterval = timerInterval * settings.multiplier;
|
||||
|
||||
if(timerInterval > settings.maxTimeout) {
|
||||
timerInterval = settings.maxTimeout;
|
||||
}
|
||||
after = timerInterval;
|
||||
pu_log('adjusting timer from '+ before +' to '+ after +'.');
|
||||
reset_timer(timerInterval);
|
||||
}
|
||||
};
|
||||
|
||||
// Construct the settings for $.ajax based on settings
|
||||
var ajaxSettings = jQuery.extend(true, {}, settings);
|
||||
if(settings.type && !ajaxSettings.dataType) ajaxSettings.dataType = settings.type;
|
||||
if(settings.sendData) ajaxSettings.data = settings.sendData;
|
||||
ajaxSettings.type = settings.method; // 'type' is used internally for jQuery. Who knew?
|
||||
ajaxSettings.ifModified = true;
|
||||
|
||||
var handle = {
|
||||
restart: function() {
|
||||
maxCalls = originalMaxCalls;
|
||||
calls = 0;
|
||||
reset_timer(timerInterval);
|
||||
return;
|
||||
},
|
||||
stop: function() {
|
||||
maxCalls = -1;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Create the function to get data
|
||||
// TODO It'd be nice to do the options.data check once (a la boostPeriod)
|
||||
function getdata() {
|
||||
var toSend = jQuery.extend(true, {}, ajaxSettings); // jQuery screws with what you pass in
|
||||
if(typeof(options.data) == 'function') {
|
||||
toSend.data = options.data();
|
||||
if(toSend.data) {
|
||||
// Handle transformations (only strings and objects are understood)
|
||||
if(typeof(toSend.data) == "number") {
|
||||
toSend.data = toSend.data.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(maxCalls == 0) {
|
||||
$.ajax(toSend);
|
||||
} else if(maxCalls > 0 && calls < maxCalls) {
|
||||
$.ajax(toSend);
|
||||
calls++;
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the tricky behind logic
|
||||
var remoteData = null;
|
||||
var prevData = null;
|
||||
|
||||
ajaxSettings.success = function(data) {
|
||||
pu_log("Successful run! (In 'success')");
|
||||
remoteData = data;
|
||||
// timerInterval = settings.minTimeout;
|
||||
};
|
||||
|
||||
ajaxSettings.complete = function(xhr, success) {
|
||||
//pu_log("Status of call: " + success + " (In 'complete')");
|
||||
if(maxCalls == -1) return;
|
||||
if(success == "success" || success == "notmodified") {
|
||||
var rawData = $.trim(xhr.responseText);
|
||||
if(rawData == 'STOP_AJAX_CALLS') {
|
||||
handle.stop();
|
||||
return;
|
||||
}
|
||||
if(prevData == rawData) {
|
||||
if(autoStop > 0) {
|
||||
noChange++;
|
||||
if(noChange == autoStop) {
|
||||
handle.stop();
|
||||
if(autoStopCallback) autoStopCallback(noChange);
|
||||
return;
|
||||
}
|
||||
}
|
||||
boostPeriod();
|
||||
} else {
|
||||
noChange = 0;
|
||||
reset_timer(settings.minTimeout);
|
||||
prevData = rawData;
|
||||
if(remoteData == null) remoteData = rawData;
|
||||
// jQuery 1.4+ $.ajax() automatically converts "data" into a JS Object for "type:json" requests now
|
||||
// For compatibility with 1.4+ and pre1.4 jQuery only try to parse actual strings, skip when remoteData is already an Object
|
||||
if((ajaxSettings.dataType === 'json') && (typeof(remoteData) === 'string') && (success == "success")) {
|
||||
remoteData = JSON.parse(remoteData);
|
||||
}
|
||||
if(settings.success) { settings.success(remoteData, success, xhr, handle); }
|
||||
if(callback) callback(remoteData, success, xhr, handle);
|
||||
}
|
||||
}
|
||||
remoteData = null;
|
||||
}
|
||||
|
||||
|
||||
ajaxSettings.error = function (xhr, textStatus) {
|
||||
//pu_log("Error message: " + textStatus + " (In 'error')");
|
||||
if(textStatus != "notmodified") {
|
||||
prevData = null;
|
||||
reset_timer(settings.minTimeout);
|
||||
}
|
||||
if(settings.error) { settings.error(xhr, textStatus); }
|
||||
};
|
||||
|
||||
// Make the first call
|
||||
$(function() { reset_timer(timerInterval); });
|
||||
|
||||
return handle;
|
||||
};
|
||||
})(jQuery);
|
290
app/assets/javascripts/local.js
Normal file
290
app/assets/javascripts/local.js
Normal file
|
@ -0,0 +1,290 @@
|
|||
$(document).ready(function(){
|
||||
//
|
||||
//function showNews(source, cat, content){
|
||||
// new Ajax.Updater(content, '/categories/' + cat, {
|
||||
// method: 'get'
|
||||
// });
|
||||
// var thisChild = source.parentNode.firstChild;
|
||||
// while (thisChild != source.parentNode.lastChild) {
|
||||
// if (thisChild.nodeType == 1 && thisChild.getAttribute("class") != "unread") {
|
||||
// thisChild.setAttribute("class", "");
|
||||
// }
|
||||
// thisChild = thisChild.nextSibling;
|
||||
// }
|
||||
// source.setAttribute("class", "active");
|
||||
//}
|
||||
|
||||
//function goToTheEnd(){
|
||||
// var ed = tinyMCE.activeEditor;
|
||||
// // This gets the root node of the editor window
|
||||
// var root = ed.dom.getRoot();
|
||||
// // And this gets the last node inside of it, so the last <p>...</p> tag
|
||||
// var lastnode = root.childNodes[root.childNodes.length - 1];
|
||||
//
|
||||
// if (tinymce.isGecko) {
|
||||
// // But firefox places the selection outside of that tag, so we need to go one level deeper:
|
||||
// lastnode = lastnode.childNodes[lastnode.childNodes.length - 1];
|
||||
// }
|
||||
// // Now, we select the node
|
||||
// ed.selection.select(lastnode);
|
||||
// // And collapse the selection to the end to put the caret there:
|
||||
// ed.selection.collapse(false);
|
||||
//}
|
||||
//
|
||||
//var myrules = {
|
||||
// '.remove': function(e){
|
||||
// el = Event.findElement(e);
|
||||
// target = el.href.replace(/.*#/, '.')
|
||||
// el.up(target).hide();
|
||||
// if (hidden_input = el.previous("input[type=hidden]")) {
|
||||
// hidden_input.value = '1'
|
||||
// }
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//Event.observe(window, 'load', function(){
|
||||
// $('container').delegate('click', myrules);
|
||||
//});
|
||||
//
|
||||
//function changeCssClass(id, newclass){
|
||||
// var obj = document.getElementById(id)
|
||||
// obj.setAttribute("class", newclass);
|
||||
// obj.setAttribute("className", newclass);
|
||||
// obj.className = newclass;
|
||||
//};
|
||||
//
|
||||
//function changeTab(container, tab){
|
||||
// $(tab).style.visibility = 'hidden';
|
||||
//};
|
||||
//
|
||||
//function Trash(source){
|
||||
// var input = document.createElement("input");
|
||||
// input.name = "deleted[reason]";
|
||||
// input.type = "hidden";
|
||||
// input.value = prompt('Enter reason', 'Violation of rule #');
|
||||
// if (input.value == null) {
|
||||
// return
|
||||
// }
|
||||
// source.appendChild(input);
|
||||
// source.submit();
|
||||
//}
|
||||
|
||||
|
||||
// User popup
|
||||
var userInfoTimeout;
|
||||
|
||||
function ShowUserPopup(source, user){
|
||||
clearInterval(userInfoTimeout);
|
||||
|
||||
hp = document.getElementById("userPopup");
|
||||
hp.style.top = source.offsetTop + "px";
|
||||
hp.style.left = source.offsetLeft - 170 + "px";
|
||||
hp.style.visibility = "Visible";
|
||||
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/users/popup/" + user + ".js",
|
||||
dataType: "script"
|
||||
});
|
||||
}
|
||||
|
||||
function HideUserPopup(){
|
||||
userInfoTimeout = setTimeout("HideUserPopupRunner();", 1000);
|
||||
}
|
||||
|
||||
function HideUserPopupRunner(){
|
||||
document.getElementById("userPopup").style.visibility = "Hidden";
|
||||
}
|
||||
|
||||
// Shoutbox
|
||||
$.PeriodicalUpdater("/shoutmsgs/index.js", {
|
||||
method: "GET",
|
||||
type: "script",
|
||||
minTimeout: 10000,
|
||||
multiplier: 2
|
||||
});
|
||||
});
|
||||
|
||||
$( function() {
|
||||
var menuContests;
|
||||
var menuGather;
|
||||
var menuMaterial;
|
||||
var menuForums;
|
||||
|
||||
$( function() {
|
||||
$('div#indexMenu div.contests').hover(function(){
|
||||
});
|
||||
});
|
||||
|
||||
$("div#shoutbox").bind("mousewheel",function(ev, delta) {
|
||||
var scrollTop = $(this).scrollTop();
|
||||
$(this).scrollTop(scrollTop-Math.round(delta));
|
||||
});
|
||||
|
||||
// Contests
|
||||
$("div#indexMenu div.contests").mouseenter(function(){
|
||||
$("div#indexItems div.contests").fadeIn(100);
|
||||
});
|
||||
|
||||
$("div#indexMenu div.contests").mouseout(function(){
|
||||
menuContests = setTimeout(function(){
|
||||
$("div#indexItems div.contests").fadeOut(100);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
$("div#indexItems div.contests").mouseenter(function(){
|
||||
clearTimeout(menuContests);
|
||||
});
|
||||
|
||||
$("div#indexItems div.contests").mouseleave(function(){
|
||||
$("div#indexItems div.contests").fadeOut(100);
|
||||
});
|
||||
|
||||
// Gather
|
||||
|
||||
$("div#indexMenu div.gather").mouseenter(function(){
|
||||
$("div#indexItems div.gather").fadeIn(100);
|
||||
});
|
||||
|
||||
$("div#indexMenu div.gather").mouseout(function(){
|
||||
menuGather = setTimeout(function(){
|
||||
$("div#indexItems div.gather").fadeOut(100);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
$("div#indexItems div.gather").mouseenter(function(){
|
||||
clearTimeout(menuGather);
|
||||
});
|
||||
|
||||
$("div#indexItems div.gather").mouseleave(function(){
|
||||
$("div#indexItems div.gather").fadeOut(100);
|
||||
});
|
||||
|
||||
// Forums
|
||||
|
||||
$("div#indexMenu div.material").mouseenter(function(){
|
||||
$("div#indexItems div.material").fadeIn(100);
|
||||
});
|
||||
|
||||
$("div#indexMenu div.material").mouseout(function(){
|
||||
menuMaterial = setTimeout(function(){
|
||||
$("div#indexItems div.material").fadeOut(100);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
$("div#indexItems div.material").mouseenter(function(){
|
||||
clearTimeout(menuMaterial);
|
||||
});
|
||||
|
||||
$("div#indexItems div.material").mouseleave(function(){
|
||||
$("div#indexItems div.material").fadeOut(100);
|
||||
});
|
||||
|
||||
// Forums
|
||||
|
||||
$("div#indexMenu div.forums").mouseenter(function(){
|
||||
$("div#indexItems div.forums").fadeIn(100);
|
||||
});
|
||||
|
||||
$("div#indexMenu div.forums").mouseout(function(){
|
||||
menuForums = setTimeout(function(){
|
||||
$("div#indexItems div.forums").fadeOut(100);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
$("div#indexItems div.forums").mouseenter(function(){
|
||||
clearTimeout(menuForums);
|
||||
});
|
||||
|
||||
$("div#indexItems div.forums").mouseleave(function(){
|
||||
$("div#indexItems div.forums").fadeOut(100);
|
||||
});
|
||||
|
||||
// Gather stuff
|
||||
|
||||
$("a#gatherInfoHide").live('click', function() {
|
||||
$("div#gatherInfo").fadeOut('slow', 0);
|
||||
});
|
||||
|
||||
$("a#gatherJoinBtn").live('click', function() {
|
||||
$('form#new_gatherer').submit();
|
||||
});
|
||||
|
||||
// Submit TODO
|
||||
|
||||
$("a.submit").live('click', function() {
|
||||
$(this).closest('form').submit()
|
||||
});
|
||||
|
||||
$('form.new_shoutmsg').submit(function(){
|
||||
$('input[type=submit]', this).attr('disabled', 'disabled');
|
||||
});
|
||||
|
||||
$('form.new_shoutmsg').submit(function(){
|
||||
$('input[type=submit]', this).attr('disabled', 'disabled');
|
||||
});
|
||||
|
||||
$('form.new_shoutmsg').live("ajax:complete", function(event,xhr,status){
|
||||
$(this)[0].reset();
|
||||
});
|
||||
|
||||
// User page
|
||||
$("td#userNavi > div > a").click(function(){
|
||||
$("td#userData").fadeOut("fast");
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: window.location.protocol + "//" + window.location.host + "/" + window.location.pathname + ".js?page=" + $(this).attr('id'),
|
||||
dataType: "script"
|
||||
});
|
||||
});
|
||||
|
||||
// Users page
|
||||
$("#users th a, #users .pagination a").live("click", function() {
|
||||
$.getScript(this.href);
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#users_search input").keyup(function() {
|
||||
$.get($("#users_search").attr("action"), $("#users_search").serialize(), null, "script");
|
||||
return false;
|
||||
});
|
||||
|
||||
// Poll page
|
||||
$("a#option").click(function() {
|
||||
});
|
||||
});
|
||||
|
||||
// User search
|
||||
var findUserWindow = "";
|
||||
|
||||
function findUser(source) {
|
||||
findUserWindow = window.open("/users/find?source=" + source, 'findUser', 'height=400,width=400,menubar=false');
|
||||
if (window.focus) {
|
||||
findUserWindow.focus();
|
||||
}
|
||||
if (findUserWindow.opener == null) {
|
||||
childWindow.opener = self;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function QuoteText(id) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/posts/quote/" + id + ".js",
|
||||
dataType: "script"
|
||||
});
|
||||
}
|
||||
|
||||
// Fields removing and adding dynamically
|
||||
|
||||
function remove_fields(link) {
|
||||
$(link).prev("input[type=hidden]").val("1");
|
||||
$(link).closest(".fields").hide();
|
||||
}
|
||||
|
||||
function add_fields(link, association, content) {
|
||||
var new_id = new Date().getTime();
|
||||
var regexp = new RegExp("new_" + association, "g")
|
||||
$(link).parent().before(content.replace(regexp, new_id));
|
||||
}
|
198
app/assets/javascripts/yetii.js
Normal file
198
app/assets/javascripts/yetii.js
Normal file
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
Yetii - Yet (E)Another Tab Interface Implementation
|
||||
version 1.5
|
||||
http://www.kminek.pl/lab/yetii/
|
||||
Copyright (c) 2007-2008 Grzegorz Wojcik
|
||||
Code licensed under the BSD License:
|
||||
http://www.kminek.pl/bsdlicense.txt
|
||||
*/
|
||||
|
||||
function Yetii() {
|
||||
|
||||
this.defaults = {
|
||||
|
||||
id: null,
|
||||
active: 1,
|
||||
interval: null,
|
||||
wait: null,
|
||||
persist: null,
|
||||
tabclass: 'tab',
|
||||
activeclass: 'active',
|
||||
callback: null,
|
||||
leavecallback: null
|
||||
|
||||
};
|
||||
|
||||
this.activebackup = null;
|
||||
|
||||
for (var n in arguments[0]) { this.defaults[n]=arguments[0][n]; };
|
||||
|
||||
this.getTabs = function() {
|
||||
|
||||
var retnode = [];
|
||||
var elem = document.getElementById(this.defaults.id).getElementsByTagName('*');
|
||||
|
||||
var regexp = new RegExp("(^|\\s)" + this.defaults.tabclass.replace(/\-/g, "\\-") + "(\\s|$)");
|
||||
|
||||
for (var i = 0; i < elem.length; i++) {
|
||||
if (regexp.test(elem[i].className)) retnode.push(elem[i]);
|
||||
}
|
||||
|
||||
return retnode;
|
||||
|
||||
};
|
||||
|
||||
this.links = document.getElementById(this.defaults.id + '-nav').getElementsByTagName('a');
|
||||
this.listitems = document.getElementById(this.defaults.id + '-nav').getElementsByTagName('li');
|
||||
|
||||
this.show = function(number) {
|
||||
|
||||
for (var i = 0; i < this.tabs.length; i++) {
|
||||
|
||||
this.tabs[i].style.display = ((i+1)==number) ? 'block' : 'none';
|
||||
|
||||
if ((i+1)==number) {
|
||||
this.addClass(this.links[i], this.defaults.activeclass);
|
||||
this.addClass(this.listitems[i], this.defaults.activeclass + 'li');
|
||||
} else {
|
||||
this.removeClass(this.links[i], this.defaults.activeclass);
|
||||
this.removeClass(this.listitems[i], this.defaults.activeclass + 'li');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (this.defaults.leavecallback && (number != this.activebackup)) this.defaults.leavecallback(this.defaults.active);
|
||||
|
||||
this.activebackup = number;
|
||||
|
||||
|
||||
this.defaults.active = number;
|
||||
|
||||
if (this.defaults.callback) this.defaults.callback(number);
|
||||
|
||||
|
||||
};
|
||||
|
||||
this.rotate = function(interval) {
|
||||
|
||||
this.show(this.defaults.active);
|
||||
this.defaults.active++;
|
||||
|
||||
if (this.defaults.active > this.tabs.length) this.defaults.active = 1;
|
||||
|
||||
|
||||
var self = this;
|
||||
|
||||
if (this.defaults.wait) clearTimeout(this.timer2);
|
||||
|
||||
this.timer1 = setTimeout(function(){self.rotate(interval);}, interval*1000);
|
||||
|
||||
};
|
||||
|
||||
this.next = function() {
|
||||
|
||||
this.defaults.active++;
|
||||
if(this.defaults.active > this.tabs.length) this.defaults.active = 1;
|
||||
this.show(this.defaults.active);
|
||||
|
||||
};
|
||||
|
||||
this.previous = function() {
|
||||
|
||||
this.defaults.active--;
|
||||
if(!this.defaults.active) this.defaults.active = this.tabs.length;
|
||||
this.show(this.defaults.active);
|
||||
|
||||
};
|
||||
|
||||
this.gup = function(name) {
|
||||
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
|
||||
var regexS = "[\\?&]"+name+"=([^&#]*)";
|
||||
var regex = new RegExp( regexS );
|
||||
var results = regex.exec( window.location.href );
|
||||
if (results == null) return null;
|
||||
else return results[1];
|
||||
};
|
||||
|
||||
this.parseurl = function(tabinterfaceid) {
|
||||
|
||||
var result = this.gup(tabinterfaceid);
|
||||
|
||||
if (result==null) return null;
|
||||
if (parseInt(result)) return parseInt(result);
|
||||
if (document.getElementById(result)) {
|
||||
for (var i=0;i<this.tabs.length;i++) {
|
||||
if (this.tabs[i].id == result) return (i+1);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
};
|
||||
|
||||
this.createCookie = function(name,value,days) {
|
||||
if (days) {
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime()+(days*24*60*60*1000));
|
||||
var expires = "; expires="+date.toGMTString();
|
||||
}
|
||||
else var expires = "";
|
||||
document.cookie = name+"="+value+expires+"; path=/";
|
||||
};
|
||||
|
||||
this.readCookie = function(name) {
|
||||
var nameEQ = name + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0;i < ca.length;i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
this.contains = function(el, item, from) {
|
||||
return el.indexOf(item, from) != -1;
|
||||
};
|
||||
|
||||
this.hasClass = function(el, className){
|
||||
return this.contains(el.className, className, ' ');
|
||||
};
|
||||
|
||||
this.addClass = function(el, className){
|
||||
if (!this.hasClass(el, className)) el.className = (el.className + ' ' + className).replace(/\s{2,}/g, ' ').replace(/^\s+|\s+$/g, '');
|
||||
};
|
||||
|
||||
this.removeClass = function(el, className){
|
||||
el.className = el.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1');
|
||||
el.className.replace(/\s{2,}/g, ' ').replace(/^\s+|\s+$/g, '');
|
||||
};
|
||||
|
||||
|
||||
this.tabs = this.getTabs();
|
||||
this.defaults.active = (this.parseurl(this.defaults.id)) ? this.parseurl(this.defaults.id) : this.defaults.active;
|
||||
if (this.defaults.persist && this.readCookie(this.defaults.id)) this.defaults.active = this.readCookie(this.defaults.id);
|
||||
this.activebackup = this.defaults.active;
|
||||
this.show(this.defaults.active);
|
||||
|
||||
var self = this;
|
||||
for (var i = 0; i < this.links.length; i++) {
|
||||
this.links[i].customindex = i+1;
|
||||
this.links[i].onclick = function(){
|
||||
|
||||
if (self.timer1) clearTimeout(self.timer1);
|
||||
if (self.timer2) clearTimeout(self.timer2);
|
||||
|
||||
self.show(this.customindex);
|
||||
if (self.defaults.persist) self.createCookie(self.defaults.id, this.customindex, 0);
|
||||
|
||||
if (self.defaults.wait) self.timer2 = setTimeout(function(){self.rotate(self.defaults.interval);}, self.defaults.wait*1000);
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
if (this.defaults.interval) this.rotate(this.defaults.interval);
|
||||
|
||||
};
|
7
app/assets/stylesheets/application.css
Normal file
7
app/assets/stylesheets/application.css
Normal file
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* This is a manifest file that'll automatically include all the stylesheets available in this directory
|
||||
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
||||
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
||||
*= require_self
|
||||
*= require_tree .
|
||||
*/
|
36
app/assets/stylesheets/sass/_mixins.sass
Normal file
36
app/assets/stylesheets/sass/_mixins.sass
Normal file
|
@ -0,0 +1,36 @@
|
|||
$text: #333333
|
||||
$bg_box: #fbfbfb
|
||||
$bg_sub: #fdfdfd
|
||||
|
||||
@mixin header
|
||||
font-weight: bold
|
||||
margin: 0
|
||||
|
||||
@mixin thin
|
||||
padding: 0
|
||||
margin: 0
|
||||
|
||||
@mixin rounded-corners
|
||||
border: 1px solid #cecece
|
||||
border-radius: 5px
|
||||
|
||||
@mixin shadow
|
||||
-moz-box-shadow: 0 0 5px #cbcbcb
|
||||
-webkit-box-shadow: 0 0 5px #cbcbcb
|
||||
box-shadow: 0 0 5px #cbcbcb
|
||||
|
||||
@mixin shadow-10px
|
||||
-moz-box-shadow: 0 0 10px #cbcbcb
|
||||
-webkit-box-shadow: 0 0 10px #cbcbcb
|
||||
box-shadow: 0 0 10px #cbcbcb
|
||||
|
||||
@mixin shadow-none
|
||||
-moz-box-shadow: none
|
||||
-webkit-box-shadow: none
|
||||
box-shadow: none
|
||||
|
||||
@mixin shaded-top
|
||||
padding: 5px 10px 0px 10px
|
||||
border-radius: 5px 5px 0px 0px
|
||||
background: url('/images/icons/article_head.png') repeat-x
|
||||
color: #ffffff
|
43
app/assets/stylesheets/sass/articles.sass
Normal file
43
app/assets/stylesheets/sass/articles.sass
Normal file
|
@ -0,0 +1,43 @@
|
|||
@import _mixins.sass
|
||||
|
||||
div
|
||||
&#matches
|
||||
min-height: 100px
|
||||
&.article
|
||||
@include rounded-corners
|
||||
@include shadow
|
||||
width: 650px
|
||||
padding: 0px
|
||||
margin-bottom: 20px
|
||||
border: 1px solid #d7d7d7
|
||||
background-color: $bg_box
|
||||
&.articleLinks
|
||||
height: 30px
|
||||
&.article
|
||||
> h1
|
||||
@include shaded-top
|
||||
margin: 0
|
||||
width: 630px
|
||||
font-size: 140%
|
||||
h1 a
|
||||
color: #ffffff
|
||||
h4
|
||||
margin: 0 3px 3px 5px
|
||||
font-size: 90%
|
||||
font-weight: bold
|
||||
color: black
|
||||
a
|
||||
font-size: 90%
|
||||
font-weight: bold
|
||||
color: black
|
||||
&:hover
|
||||
color: #707070
|
||||
div.content
|
||||
padding: 5px 10px 10px 10px
|
||||
div
|
||||
margin: 5px 3px 0 3px
|
||||
&.indented
|
||||
margin: 2px 2px 2px 15px
|
||||
&.article div.footer
|
||||
margin: 0
|
||||
padding: 10px
|
24
app/assets/stylesheets/sass/brackets.sass
Normal file
24
app/assets/stylesheets/sass/brackets.sass
Normal file
|
@ -0,0 +1,24 @@
|
|||
@mixin bracket-cell
|
||||
border: 1px solid #D9D9D9
|
||||
border-width: 1px 1px 1px 0
|
||||
width: 110px
|
||||
height: 14px
|
||||
|
||||
table.brackets
|
||||
border-collapse: collapse
|
||||
td
|
||||
font-size: 11px
|
||||
overflow: hidden
|
||||
&.empty
|
||||
width: 90px
|
||||
height: 14px
|
||||
&.team
|
||||
@include bracket-cell
|
||||
border-width: 1px 1px 1px 0
|
||||
background-color: #fdfdfd
|
||||
&.connector
|
||||
@include bracket-cell
|
||||
border-width: 0 1px 0 0
|
||||
|
||||
select
|
||||
width: 100px
|
36
app/assets/stylesheets/sass/comments.sass
Normal file
36
app/assets/stylesheets/sass/comments.sass
Normal file
|
@ -0,0 +1,36 @@
|
|||
@import _mixins.sass
|
||||
|
||||
div
|
||||
&.commentNew
|
||||
width: 340px
|
||||
height: 300px
|
||||
&.comments
|
||||
width: 410px
|
||||
&.commentHidden
|
||||
top: auto
|
||||
position: fixed
|
||||
visibility: hidden
|
||||
display: none
|
||||
&.commentBox
|
||||
margin: 5px auto 30px auto
|
||||
width: 400px
|
||||
h5
|
||||
@include shadow
|
||||
width: 400px
|
||||
height: 15px
|
||||
padding: 2px 5px 1px 5px
|
||||
background: url('/images/icons/article_head.png') repeat
|
||||
color: white
|
||||
font-size: 11px
|
||||
a
|
||||
color: black
|
||||
&:hover
|
||||
color: #d4d4d4
|
||||
div
|
||||
padding: 5px
|
||||
width: 400px
|
||||
background-color: $bg_sub
|
||||
overflow-x: hidden
|
||||
|
||||
blockquote.commentQuote:first-line
|
||||
font-weight: bold
|
26
app/assets/stylesheets/sass/errors.sass
Normal file
26
app/assets/stylesheets/sass/errors.sass
Normal file
|
@ -0,0 +1,26 @@
|
|||
div.fieldWithErrors
|
||||
display: inline-block
|
||||
margin: 0
|
||||
padding: 0
|
||||
color: red
|
||||
|
||||
#errorExplanation
|
||||
width: 400px
|
||||
margin-bottom: 20px
|
||||
padding: 7px 7px 7px 7px
|
||||
background-color: #f0f0f0
|
||||
h2
|
||||
margin: -7px
|
||||
padding: 5px
|
||||
background-color: #c00
|
||||
color: #fff
|
||||
text-align: left
|
||||
font-weight: bold
|
||||
font-size: 12px
|
||||
p
|
||||
padding: 5px
|
||||
visibility: hidden
|
||||
color: #333
|
||||
ul li
|
||||
font-size: 12px
|
||||
list-style: url('/images/icons/list-black.gif')
|
17
app/assets/stylesheets/sass/flash.sass
Normal file
17
app/assets/stylesheets/sass/flash.sass
Normal file
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Flash messages
|
||||
*/
|
||||
|
||||
div
|
||||
&.loginMsg, &.flashMsg
|
||||
padding: 5px
|
||||
font-weight: bold
|
||||
&.loginOk
|
||||
color: green
|
||||
&.loginFail
|
||||
color: red
|
||||
&.flashMsg
|
||||
background-color: green
|
||||
color: white
|
||||
&.flashError
|
||||
background-color: red
|
107
app/assets/stylesheets/sass/forums.sass
Normal file
107
app/assets/stylesheets/sass/forums.sass
Normal file
|
@ -0,0 +1,107 @@
|
|||
@import _mixins.sass
|
||||
|
||||
div
|
||||
&#indexForums
|
||||
width: 940px
|
||||
padding-bottom: 5px
|
||||
margin: 0 auto 0 auto
|
||||
&.forums
|
||||
width: 100%
|
||||
margin-left: auto
|
||||
margin-right: auto
|
||||
> div.category
|
||||
width: 100%
|
||||
margin-left: auto
|
||||
margin-right: auto
|
||||
padding: 0px
|
||||
margin: 5px
|
||||
> table.body
|
||||
width: 100%
|
||||
margin: 0 auto 0 auto
|
||||
padding: 0
|
||||
border: 1px solid #d8e4eb
|
||||
border-collapse: collapse
|
||||
th
|
||||
margin: 0
|
||||
padding: 3px
|
||||
border: 1px solid #d8e4eb
|
||||
background: #cde7f2 repeat-x url('/images/forums/forum_gradient2.png')
|
||||
vertical-align: middle
|
||||
font-size: 13px
|
||||
text-align: left
|
||||
&.header
|
||||
padding: 5px 5px 5px 3px
|
||||
background: url('/images/forums/forum_gradient.jpg') repeat-x center #2a536d
|
||||
color: #f7fafd
|
||||
font-size: 14px
|
||||
font-weight: bold
|
||||
text-align: left
|
||||
td
|
||||
padding: 0px 4px 2px 8px
|
||||
border: 1px solid #d8e4eb
|
||||
height: 38px
|
||||
background-color: #f9fafb
|
||||
vertical-align: middle
|
||||
text-align: left
|
||||
&.forum
|
||||
height: 48px
|
||||
&.bullet
|
||||
background: url('/images/forums/forum_icon_read.png') no-repeat center #f9fafb
|
||||
width: 38px
|
||||
height: 36px
|
||||
&.hl
|
||||
background: url('/images/forums/forum_icon_unread.png') no-repeat center #f9fafb
|
||||
|
||||
table
|
||||
&#topic
|
||||
border: 1px solid #d8e4eb
|
||||
border-collapse: collapse
|
||||
width: 100%
|
||||
&#topic>thead>tr>th, &#topic>tbody>tr>td, &#topic>tbody>tr>th, &#topic>tfoot>tr>th
|
||||
border: 1px solid #d8e4eb
|
||||
background-color: #f9fafb
|
||||
padding: 5px
|
||||
&#topic>thead>tr>th, &#topic>tfoot>tr>th
|
||||
background: url('/images/forums/forum_gradient.jpg') repeat-x center #2a536d
|
||||
color: #f7fafd
|
||||
font-size: 14px
|
||||
font-weight: bold
|
||||
&#topic>thead>tr>th a, &#topic>tfoot>tr>th a
|
||||
color: #e3f0fd
|
||||
font-weight: bold
|
||||
&#topic
|
||||
th.seperator
|
||||
height: 5px
|
||||
padding: 0
|
||||
background: url('/images/forums/forum_gradient.jpg') repeat-x center #2a536d
|
||||
font-size: 11px
|
||||
td.avatar
|
||||
width: 160px
|
||||
vertical-align: top
|
||||
th.header
|
||||
background: url('/images/forums/forum_gradient2.png') repeat-x #cde7f2
|
||||
height: 10px
|
||||
font-size: 11px
|
||||
td
|
||||
&.actions
|
||||
font-weight: bold
|
||||
&.signature
|
||||
font-size: 10px
|
||||
&.text
|
||||
vertical-align: top
|
||||
padding-top: 2px
|
||||
tr#reply
|
||||
display: none
|
||||
blockquote
|
||||
padding: 5px
|
||||
fieldset
|
||||
margin: 3px 5px 3px 5px
|
||||
padding: 3px 5px 5px 13px
|
||||
display: block
|
||||
border: 1px solid #ccc
|
||||
background-color: #fbfdff
|
||||
blockquote
|
||||
border: 0
|
||||
padding: 3px 2px 2px 2px
|
||||
margin: 0
|
||||
|
19
app/assets/stylesheets/sass/gather.sass
Normal file
19
app/assets/stylesheets/sass/gather.sass
Normal file
|
@ -0,0 +1,19 @@
|
|||
div
|
||||
&#gatherInfo table td
|
||||
vertical-align: top
|
||||
&.gatherLeftBox
|
||||
width: 170px
|
||||
height: 320px
|
||||
|
||||
&.gatherMiddleBox, &.gatherRightBox
|
||||
width: 170px
|
||||
height: 320px
|
||||
&#gatherStatus
|
||||
|
||||
table
|
||||
&#gatherVotes
|
||||
border-collapse: collapse
|
||||
&.gatherVotes td
|
||||
overflow: hidden
|
||||
margin: 0px
|
||||
padding: 1px 0px 0px 1px
|
203
app/assets/stylesheets/sass/general.sass
Normal file
203
app/assets/stylesheets/sass/general.sass
Normal file
|
@ -0,0 +1,203 @@
|
|||
@import _mixins.sass
|
||||
|
||||
html, body
|
||||
padding: 0
|
||||
margin: 0
|
||||
height: 100%
|
||||
background: repeat url('/images/index/index_pattern.png')
|
||||
color: $text
|
||||
font-family: Verdana, Arial, sans-serif
|
||||
font-size: 11px
|
||||
|
||||
h1
|
||||
width: 100%
|
||||
height: 25px
|
||||
font-size: 20px
|
||||
|
||||
h2
|
||||
@include header
|
||||
padding: 8px 0 3px 0
|
||||
font-size: 16px
|
||||
|
||||
h3
|
||||
@include header
|
||||
padding: 3px 0 3px 0px
|
||||
font-size: 13px
|
||||
|
||||
h4
|
||||
@include header
|
||||
padding: 0 0 3px 0
|
||||
font-size: 11px
|
||||
|
||||
h5
|
||||
@include header
|
||||
padding: 0 0 3px 0
|
||||
font-size: 9px
|
||||
|
||||
div, form
|
||||
@thin
|
||||
|
||||
p
|
||||
margin: 0
|
||||
padding: 3px 2px 3px 2px
|
||||
|
||||
img
|
||||
margin: 0
|
||||
padding: 3px
|
||||
border: 0
|
||||
|
||||
a
|
||||
color: #2f79ab
|
||||
text-decoration: none
|
||||
&:visited
|
||||
color: #2f79ab
|
||||
text-decoration: none
|
||||
&:hover
|
||||
color: #6890ab
|
||||
text-decoration: none
|
||||
&[name]
|
||||
color: black
|
||||
&:hover
|
||||
text-decoration: none
|
||||
|
||||
ol
|
||||
margin: 0
|
||||
|
||||
ul
|
||||
margin: 0
|
||||
padding: 0 2px 5px 10px
|
||||
li
|
||||
margin: 0 0 0 10px
|
||||
list-style-type: square
|
||||
|
||||
ol li
|
||||
margin: 0 0 0 10px
|
||||
|
||||
blockquote
|
||||
@include rounded-corners
|
||||
margin: 3px 5px 3px 7px
|
||||
padding: 3px 3px 3px 13px
|
||||
display: block
|
||||
border: 1px solid #ccc
|
||||
background-color: #fcfcfc
|
||||
|
||||
@mixin input-general
|
||||
@include shadow-10px
|
||||
@include rounded-corners
|
||||
margin-top: 3px
|
||||
background-color: #f7f7f7
|
||||
color: #3a3a3a
|
||||
|
||||
input
|
||||
margin: 2px
|
||||
padding: 2px 3px 2px 3px
|
||||
|
||||
&[type=text], &[type=password]
|
||||
@include input-general
|
||||
&[type=text]:focus
|
||||
@include input-general
|
||||
border: 1px solid #ce6f6f
|
||||
&[type=submit]
|
||||
@include input-general
|
||||
@include rounded-corners
|
||||
padding: 0px 5px 2px 5px
|
||||
background-color: #f7f7f7
|
||||
&:hover
|
||||
cursor: pointer
|
||||
border: 1px solid #dddbdb
|
||||
&:disabled
|
||||
background-color: #f7f7f7
|
||||
|
||||
|
||||
.clear
|
||||
clear: both
|
||||
|
||||
.minitext
|
||||
font-size: 80%
|
||||
|
||||
.center
|
||||
text-align: center
|
||||
|
||||
.centered
|
||||
display: block
|
||||
margin-right: auto
|
||||
margin-left: auto
|
||||
|
||||
.box
|
||||
@include shadow
|
||||
@include rounded-corners
|
||||
background: url('/images/icons/article_background.png') no-repeat $bg_box
|
||||
margin: 4px
|
||||
padding: 10px 10px 10px 15px
|
||||
color: #3a3a3a
|
||||
overflow-x: hidden
|
||||
h2:first-of-type
|
||||
@include shaded-top
|
||||
margin: -10px auto 10px -18px
|
||||
width: 110%
|
||||
padding-top: 5px
|
||||
padding-bottom: 5px
|
||||
font-size: 140%
|
||||
> a
|
||||
color: #fff
|
||||
|
||||
.nbox
|
||||
margin: 4px
|
||||
padding: 10px 10px 10px 15px
|
||||
overflow-x: hidden
|
||||
|
||||
.sub
|
||||
@include shadow-none
|
||||
border: 0
|
||||
background: none
|
||||
margin: 5px
|
||||
padding: 5px
|
||||
|
||||
.left
|
||||
display: inline-block
|
||||
left: 0
|
||||
float: left
|
||||
|
||||
.right
|
||||
display: inline-block
|
||||
right: 0
|
||||
float: right
|
||||
|
||||
.big
|
||||
width: 65%
|
||||
|
||||
.big2
|
||||
width: 62%
|
||||
|
||||
.small
|
||||
width: 18%
|
||||
|
||||
.small2
|
||||
width: 30%
|
||||
|
||||
.equal
|
||||
width: 48%
|
||||
|
||||
.wide
|
||||
width: 95%
|
||||
|
||||
.wide2
|
||||
width: 100%
|
||||
|
||||
.bold
|
||||
font-weight: bold
|
||||
|
||||
.hidden
|
||||
visibility: hidden
|
||||
|
||||
.green
|
||||
color: green
|
||||
|
||||
.yellow
|
||||
color: #ceb006
|
||||
|
||||
.red
|
||||
color: #ff0000 !important
|
||||
|
||||
span.description
|
||||
color: #5c5c5c
|
203
app/assets/stylesheets/sass/index.sass
Normal file
203
app/assets/stylesheets/sass/index.sass
Normal file
|
@ -0,0 +1,203 @@
|
|||
@import _mixins.sass
|
||||
|
||||
div
|
||||
&#indexContainer
|
||||
min-height: 100%
|
||||
position: relative
|
||||
background: repeat-x url('/images/index/index_bg.png')
|
||||
padding-bottom: 30px
|
||||
|
||||
&#indexMain
|
||||
margin: 0 auto 0 auto
|
||||
width: 1200px
|
||||
padding-bottom: 20px
|
||||
|
||||
&#indexBanner
|
||||
width: 100%
|
||||
height: 194px
|
||||
background: no-repeat url('/images/index/index_header.png')
|
||||
position: relative
|
||||
|
||||
&#indexLogo
|
||||
position: absolute
|
||||
top: 0px
|
||||
left: 100px
|
||||
width: 330px
|
||||
height: 194px
|
||||
//top: 130px
|
||||
//left: 265px
|
||||
//width: 250px
|
||||
//height: 50px
|
||||
visibility: hidden
|
||||
background-color: transparent
|
||||
|
||||
&#indexLinks
|
||||
width: 850px
|
||||
height: 25px
|
||||
padding-top: 3px
|
||||
margin-left: 250px
|
||||
color: #ffffff
|
||||
text-align: right
|
||||
span.gather
|
||||
color: #CC6600
|
||||
> a
|
||||
color: #ffffff
|
||||
&:hover
|
||||
color: #d5d5d5
|
||||
span
|
||||
color: #cc0000
|
||||
> a
|
||||
color: #cc0000
|
||||
|
||||
&#indexLogin
|
||||
height: 45px
|
||||
margin: 5px auto auto 710px
|
||||
font-size: 10px
|
||||
color: #ffffff
|
||||
div
|
||||
&.logged
|
||||
text-align: center
|
||||
font-size: 11px
|
||||
&.button
|
||||
width: 75px
|
||||
height: 18px
|
||||
padding-top: 5px
|
||||
margin: 10px 1px 0px 2px
|
||||
background-image: url('/images/icons/button.png')
|
||||
font-size: 12px
|
||||
font-weight: bold
|
||||
float: left
|
||||
&:hover
|
||||
background-image: url('/images/icons/button_hl.png')
|
||||
a
|
||||
color: #ffffff
|
||||
td#links
|
||||
text-align: right
|
||||
input
|
||||
&[type=text], &[type=password]
|
||||
width: 100px
|
||||
&[type=submit]
|
||||
@include shadow
|
||||
height: 21px
|
||||
width: 20px
|
||||
border: 1px solid #cecece
|
||||
background-color: #f7f7f7
|
||||
color: #3a3a3a
|
||||
cursor: pointer
|
||||
|
||||
&#indexMenu
|
||||
margin-top: 8px
|
||||
margin-left: 500px
|
||||
height: 33px
|
||||
div
|
||||
width: 143px
|
||||
height: 33px
|
||||
color: #ffffff
|
||||
float: left
|
||||
&.contests
|
||||
background-image: url('/images/index/menu_contests.png')
|
||||
&:hover
|
||||
background-image: url('/images/index/menu_contests_shaded.png')
|
||||
cursor: pointer
|
||||
&.gather
|
||||
margin-left: 5px
|
||||
background-image: url('/images/index/menu_gather.png')
|
||||
&:hover
|
||||
background-image: url('/images/index/menu_gather_shaded.png')
|
||||
cursor: pointer
|
||||
&.material
|
||||
margin-left: 5px
|
||||
background-image: url('/images/index/menu_material.png')
|
||||
&:hover
|
||||
background-image: url('/images/index/menu_material_shaded.png')
|
||||
cursor: pointer
|
||||
&.forums
|
||||
margin-left: 5px
|
||||
background-image: url('/images/index/menu_forums.png')
|
||||
&:hover
|
||||
background-image: url('/images/index/menu_forums_shaded.png')
|
||||
cursor: pointer
|
||||
|
||||
&#indexItems div
|
||||
display: none
|
||||
position: absolute
|
||||
left: 495px
|
||||
margin-top: 6px
|
||||
width: 143px
|
||||
text-align: right
|
||||
font-size: 13px
|
||||
&.gather
|
||||
left: 645px
|
||||
&.material
|
||||
left: 795px
|
||||
&.forums
|
||||
left: 943px
|
||||
a
|
||||
color: #ffffff
|
||||
&:hover
|
||||
color: #d6d5d5
|
||||
|
||||
&#indexMainarea
|
||||
padding: 10px 100px 10px 150px
|
||||
|
||||
&#indexContent
|
||||
width: 650px
|
||||
margin-left: 15px
|
||||
margin-right: 15px
|
||||
float: left
|
||||
padding: 0
|
||||
|
||||
&#indexRight
|
||||
padding-top: 15px
|
||||
float: left
|
||||
&.indexBox
|
||||
@include rounded-corners
|
||||
@include shadow
|
||||
width: 220px
|
||||
padding-bottom: 10px
|
||||
margin-bottom: 15px
|
||||
background-color: $bg_box
|
||||
div
|
||||
&.header
|
||||
@include shaded-top
|
||||
margin: 0
|
||||
padding-top: 5px
|
||||
height: 25px
|
||||
font-size: 14px
|
||||
font-weight: bold
|
||||
&.body
|
||||
width: 100%
|
||||
text-align: left
|
||||
&.content
|
||||
margin: 0
|
||||
padding: 6px 5px 0 10px
|
||||
font-size: 10px
|
||||
h3
|
||||
margin: 0 2px 2px 2px
|
||||
padding-top: 7px
|
||||
font-size: 10px
|
||||
ol, li
|
||||
padding: 1px 2px 2px 0px
|
||||
list-style-type: none
|
||||
div.movie
|
||||
padding-left: 10px
|
||||
width: 110px
|
||||
text-align: center
|
||||
|
||||
&#indexPosts
|
||||
padding: 5px
|
||||
|
||||
&#indexFooter
|
||||
position: absolute
|
||||
width: 100%
|
||||
height: 20px
|
||||
bottom: 0
|
||||
padding-top: 5px
|
||||
background: url('/images/index/index_footer.png') repeat-x center #2a536d
|
||||
text-align: center
|
||||
font-size: 80%
|
||||
color: #fff
|
||||
a
|
||||
font-weight: bold
|
||||
color: #fff
|
||||
text-transform: uppercase
|
40
app/assets/stylesheets/sass/rounds.sass
Normal file
40
app/assets/stylesheets/sass/rounds.sass
Normal file
|
@ -0,0 +1,40 @@
|
|||
div
|
||||
&#roundEvents
|
||||
margin: 0 auto 0 auto
|
||||
width: 530px
|
||||
&#roundTimeline
|
||||
background-color: black
|
||||
background-image: url('/images/icons/round_timeline.gif')
|
||||
background-repeat: repeat-y
|
||||
width: 5px
|
||||
height: 100px
|
||||
margin-top: 0
|
||||
float: left
|
||||
&#roundAliens, &#roundMarines
|
||||
float: left
|
||||
width: 250px
|
||||
background-color: black
|
||||
&.roundEvent
|
||||
height: 15px
|
||||
width: 100px
|
||||
padding: 0 2px 0 2px
|
||||
font-size: 8px
|
||||
text-align: center
|
||||
overflow: visible
|
||||
white-space: nowrap
|
||||
vertical-align: middle
|
||||
background: black
|
||||
&.roundFrag
|
||||
span
|
||||
display: inline-block
|
||||
padding-top: 2px
|
||||
vertical-align: top
|
||||
img
|
||||
padding: 0 1px 0 1px
|
||||
margin: 0
|
||||
&#roundAliens div.roundEvent
|
||||
color: #fdbf31
|
||||
text-align: right
|
||||
&#roundMarines div.roundEvent
|
||||
color: #0080c0
|
||||
text-align: left
|
28
app/assets/stylesheets/sass/shoutbox.sass
Normal file
28
app/assets/stylesheets/sass/shoutbox.sass
Normal file
|
@ -0,0 +1,28 @@
|
|||
div#shoutbox
|
||||
width: 150px
|
||||
padding: 2px
|
||||
margin: 2px
|
||||
overflow-y: hidden
|
||||
overflow-x: hidden
|
||||
|
||||
input
|
||||
&#shoutbox_text
|
||||
width: 150px
|
||||
&.counter
|
||||
width: 25px !important
|
||||
border: 0
|
||||
background: transparent
|
||||
|
||||
div
|
||||
&.shoutmsgBox
|
||||
height: 100px
|
||||
overflow-y: scroll
|
||||
&.shoutmsg
|
||||
display: block
|
||||
padding-left: 5px
|
||||
font-size: 90%
|
||||
text-indent: -5px
|
||||
|
||||
a
|
||||
&.shoutmsgDel, &[data-method="delete"]
|
||||
color: red
|
72
app/assets/stylesheets/sass/special.sass
Normal file
72
app/assets/stylesheets/sass/special.sass
Normal file
|
@ -0,0 +1,72 @@
|
|||
div
|
||||
&#matchesTab div.tabs
|
||||
min-height: 100px
|
||||
&#indexPoll
|
||||
font-size: 80%
|
||||
margin-left: 10px
|
||||
&#pollOptions
|
||||
img
|
||||
padding-top: 5px
|
||||
span
|
||||
vertical-align: top
|
||||
&#userFinder
|
||||
padding: 8px 8px 0 8px
|
||||
margin: 10px
|
||||
&.userDataBox
|
||||
min-height: 220px
|
||||
|
||||
td
|
||||
&#userNavi
|
||||
vertical-align: top
|
||||
padding: 5px
|
||||
&#userData
|
||||
padding-left: 15px
|
||||
padding-top: 20px
|
||||
vertical-align: top
|
||||
width: 450px
|
||||
|
||||
div
|
||||
&.userFields
|
||||
margin-left: 10px
|
||||
display: block
|
||||
&#userAvatar
|
||||
display: inline-block
|
||||
margin-left: 13px
|
||||
width: 150px
|
||||
&#userPopup
|
||||
visibility: hidden
|
||||
position: absolute
|
||||
width: 150px
|
||||
height: 180px
|
||||
font-size: 80%
|
||||
&#userInfo h4
|
||||
margin: 1px auto 1px auto
|
||||
display: block
|
||||
padding: 0
|
||||
&#serverLog
|
||||
width: 560px
|
||||
height: 200px
|
||||
padding: 3px
|
||||
border: 2px inset #e6e6e6
|
||||
overflow-y: scroll
|
||||
overflow-x: hidden
|
||||
pre
|
||||
&.command
|
||||
display: block
|
||||
background-color: #eaffef
|
||||
font-weight: bold
|
||||
&.response
|
||||
display: block
|
||||
background-color: #fbfdff
|
||||
&#stream
|
||||
width: 800px
|
||||
|
||||
img.bar
|
||||
|
||||
table#movie td
|
||||
padding-left: 15px
|
||||
padding-right: 15px
|
||||
min-width: 166px
|
||||
|
||||
div.article > h1.sender
|
||||
background: #8a2d27
|
36
app/assets/stylesheets/sass/tables.sass
Normal file
36
app/assets/stylesheets/sass/tables.sass
Normal file
|
@ -0,0 +1,36 @@
|
|||
@import _mixins.sass
|
||||
|
||||
table
|
||||
&.data
|
||||
@include shadow
|
||||
width: 100%
|
||||
margin: 5px 3px 8px 3px
|
||||
border-collapse: collapse
|
||||
background-color: #fafafa
|
||||
text-align: left
|
||||
border: 1px solid #cecece
|
||||
th
|
||||
color: white
|
||||
background-image: url('/images/icons/article_head.png')
|
||||
background-repeat: repeat-x
|
||||
a
|
||||
color: white
|
||||
tr
|
||||
&.odd
|
||||
background-color: #b0d1e8
|
||||
&.even
|
||||
background-color: #FFFFFF
|
||||
td, th
|
||||
padding: 2px 5px 2px 5px
|
||||
tr
|
||||
&.red
|
||||
background-color: #FFC0CB
|
||||
color: black
|
||||
&.green
|
||||
background-color: #bfffbf
|
||||
color: black
|
||||
&.split
|
||||
width: 100%
|
||||
th
|
||||
text-align: right
|
||||
width: 50%
|
37
app/assets/stylesheets/sass/tabs.sass
Normal file
37
app/assets/stylesheets/sass/tabs.sass
Normal file
|
@ -0,0 +1,37 @@
|
|||
@import _mixins.sass
|
||||
|
||||
ul.tabs
|
||||
padding-bottom: 4px
|
||||
padding-left: 20px
|
||||
li
|
||||
margin: 0 2px 0 0
|
||||
float: left
|
||||
list-style-type: none
|
||||
list-style-image: none
|
||||
a
|
||||
@include shadow-10px
|
||||
display: block
|
||||
float: left
|
||||
height: 18px
|
||||
padding-top: 5px
|
||||
padding: 5px 10px 0px 10px
|
||||
-webkit-border-top-left-radius: 5px
|
||||
-webkit-border-top-right-radius: 5px
|
||||
-moz-border-radius-topleft: 5px
|
||||
-moz-border-radius-topright: 5px
|
||||
border-top-left-radius: 5px
|
||||
border-top-right-radius: 5px
|
||||
background-color: #255278
|
||||
font-weight: bold
|
||||
text-decoration: none
|
||||
text-align: center
|
||||
color: #ffffff
|
||||
&:hover
|
||||
background-color: #0e5490
|
||||
&.active
|
||||
cursor: default
|
||||
background-color: #891a06
|
||||
|
||||
div.tabs
|
||||
margin: 5px
|
||||
margin-top: 19px
|
10
app/controllers/about_controller.rb
Normal file
10
app/controllers/about_controller.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
class AboutController < ApplicationController
|
||||
def staff
|
||||
end
|
||||
|
||||
def adminpanel
|
||||
end
|
||||
|
||||
def statistics
|
||||
end
|
||||
end
|
74
app/controllers/application_controller.rb
Normal file
74
app/controllers/application_controller.rb
Normal file
|
@ -0,0 +1,74 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
helper :all
|
||||
helper_method :cuser, :strip, :return_here
|
||||
|
||||
before_filter :update_user
|
||||
before_filter :set_controller_and_action_names
|
||||
|
||||
protect_from_forgery
|
||||
respond_to :html, :js
|
||||
|
||||
include Exceptions
|
||||
|
||||
# Global methods
|
||||
|
||||
def cuser
|
||||
@cuser ||= User.find(session[:user]) if session[:user]
|
||||
end
|
||||
|
||||
def return_here
|
||||
session[:return_to] = request.url
|
||||
end
|
||||
|
||||
def return_to
|
||||
addr = session[:return_to]
|
||||
session[:return_to] = nil
|
||||
redirect_to addr
|
||||
end
|
||||
|
||||
def redirect_to_back
|
||||
if request.env["HTTP_REFERER"]
|
||||
redirect_to request.env["HTTP_REFERER"]
|
||||
else
|
||||
redirect_to "/"
|
||||
end
|
||||
rescue
|
||||
redirect_to "/"
|
||||
end
|
||||
|
||||
def redirect_to_home
|
||||
redirect_to :controller => "articles", :action => "news_index"
|
||||
end
|
||||
|
||||
def rescue_action(exception)
|
||||
case exception
|
||||
when AccessError
|
||||
render :text => t(:access_denied), :layout => true
|
||||
when Error
|
||||
render :text => exception.message, :layout => true
|
||||
when ActiveRecord::StaleObjectError
|
||||
render :text => t(:application_stale)
|
||||
else
|
||||
super exception
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_user
|
||||
if cuser
|
||||
Time.zone = cuser.time_zone
|
||||
cuser.update_attribute :lastvisit, DateTime.now if cuser.lastvisit < 2.minutes.ago
|
||||
|
||||
if cuser.banned? Ban::TYPE_SITE
|
||||
session[:user] = nil
|
||||
@cuser = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def set_controller_and_action_names
|
||||
@current_controller = controller_name
|
||||
@current_action = action_name
|
||||
end
|
||||
end
|
85
app/controllers/articles_controller.rb
Normal file
85
app/controllers/articles_controller.rb
Normal file
|
@ -0,0 +1,85 @@
|
|||
class ArticlesController < ApplicationController
|
||||
before_filter :get_article, :only => [:show, :edit, :update, :cleanup, :destroy]
|
||||
|
||||
def index
|
||||
@categories = Category.ordered.nospecial.domain Category::DOMAIN_ARTICLES
|
||||
end
|
||||
|
||||
def news_index
|
||||
@cat = params[:cat] ? Category.find(params[:cat]) : Article.onlynews.ordered.first.category
|
||||
@news = Article.with_comments.ordered.limited.nodrafts.category @cat
|
||||
@categories = Category.ordered.domain Category::DOMAIN_NEWS
|
||||
@nobody = true
|
||||
end
|
||||
|
||||
def news_archive
|
||||
@news = Article.with_comments.ordered.nodrafts.onlynews
|
||||
end
|
||||
|
||||
def admin
|
||||
raise AccessError unless cuser and cuser.admin?
|
||||
@articles = {"Drafts" => Article.drafts.ordered, "Special" => Article.category(Category::SPECIAL).ordered}
|
||||
end
|
||||
|
||||
def show
|
||||
raise AccessError unless @article.can_show? cuser
|
||||
@article.read_by! cuser if cuser
|
||||
# @article.record_view_count(request.remote_ip, cuser.nil?)
|
||||
@nobody = true
|
||||
end
|
||||
|
||||
def new
|
||||
@article = Article.new
|
||||
@article.text_coding = Article::CODING_HTML
|
||||
raise AccessError unless @article.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @article.can_update? cuser
|
||||
@file = DataFile.new
|
||||
@file.directory_id = Directory::ARTICLES
|
||||
@file.article = @article
|
||||
end
|
||||
|
||||
def create
|
||||
@article = Article.new params[:article]
|
||||
@article.user = cuser
|
||||
raise AccessError unless @article.can_create? cuser
|
||||
|
||||
if @article.save
|
||||
flash[:notice] = t(:articles_create)
|
||||
redirect_to @article
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @article.can_update? cuser, params[:article]
|
||||
if @article.update_attributes params[:article]
|
||||
flash[:notice] = t(:articles_update)
|
||||
redirect_to @article
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup
|
||||
raise AccessError unless @article.can_update? cuser
|
||||
@article.text = strip(@article.text)
|
||||
@article.save!
|
||||
redirect_to @article
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @article.can_destroy? cuser
|
||||
@article.destroy
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_article
|
||||
@article = Article.find params[:id]
|
||||
end
|
||||
end
|
57
app/controllers/bans_controller.rb
Normal file
57
app/controllers/bans_controller.rb
Normal file
|
@ -0,0 +1,57 @@
|
|||
class BansController < ApplicationController
|
||||
before_filter :get_ban, :only => [:show, :edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@bans = Ban.ordered
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def refresh
|
||||
Ban.refresh
|
||||
end
|
||||
|
||||
def new
|
||||
@ban = Ban.new
|
||||
raise AccessError unless @ban.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @ban.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@ban = Ban.new(params[:ban])
|
||||
raise AccessError unless @ban.can_create? cuser
|
||||
|
||||
if @ban.save
|
||||
flash[:notice] = t(:bans_create)
|
||||
redirect_to(@ban)
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @ban.can_update? cuser
|
||||
if @ban.update_attributes(params[:ban])
|
||||
flash[:notice] = t(:bans_update)
|
||||
redirect_to(@ban)
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @ban.can_destroy? cuser
|
||||
@ban.destroy
|
||||
redirect_to(bans_url)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_ban
|
||||
@ban = Ban.find(params[:id])
|
||||
end
|
||||
end
|
40
app/controllers/brackets_controller.rb
Normal file
40
app/controllers/brackets_controller.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
class BracketsController < ApplicationController
|
||||
before_filter :get_bracket, :only => [:show, :edit, :update, :destroy]
|
||||
|
||||
def edit
|
||||
raise AccessError unless @bracket.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@bracket = Bracket.new params[:bracket]
|
||||
raise AccessError unless @bracket.can_create? cuser
|
||||
|
||||
if @bracket.save
|
||||
flash[:notice] = t(:brackets_create)
|
||||
end
|
||||
|
||||
redirect_to edit_contest_path(@bracket.contest)
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @bracket.can_update? cuser
|
||||
|
||||
if @bracket.update_attributes params[:bracket] and @bracket.update_cells(params[:cell])
|
||||
flash[:notice] = t(:brackets_update)
|
||||
end
|
||||
|
||||
render :action => "edit"
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @bracket.can_destroy? cuser
|
||||
@bracket.destroy
|
||||
redirect_to edit_contest_path(@bracket.contest)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_bracket
|
||||
@bracket = Bracket.find(params[:id])
|
||||
end
|
||||
end
|
67
app/controllers/categories_controller.rb
Normal file
67
app/controllers/categories_controller.rb
Normal file
|
@ -0,0 +1,67 @@
|
|||
class CategoriesController < ApplicationController
|
||||
before_filter :get_category, :except => [:index, :new, :create]
|
||||
|
||||
def show
|
||||
if [Category::DOMAIN_ARTICLES, Category::DOMAIN_NEWS].include? @category.domain
|
||||
@articles = Article.with_comments.ordered.limited.nodrafts.category params[:id]
|
||||
Category.find(params[:id]).read_by! cuser if cuser
|
||||
render :partial => "articles/article", :collection => @articles.to_a
|
||||
end
|
||||
end
|
||||
|
||||
def index
|
||||
@categories = Category.ordered
|
||||
end
|
||||
|
||||
def new
|
||||
@category = Category.new
|
||||
raise AccessError unless @category.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @category.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@category = Category.new params[:category]
|
||||
raise AccessError unless @category.can_create? cuser
|
||||
|
||||
if @category.save
|
||||
@category.update_attribute :sort, @category.id
|
||||
flash[:notice] = t(:articles_category)
|
||||
redirect_to :categories
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @category.can_update? cuser
|
||||
if @category.update_attributes params[:category]
|
||||
flash[:notice] = t(:articles_category_update)
|
||||
redirect_to :categories
|
||||
end
|
||||
end
|
||||
|
||||
def up
|
||||
raise AccessError unless @category.can_update? cuser
|
||||
@category.move_up(["domain = ?", @category.domain], "sort")
|
||||
redirect_to :categories
|
||||
end
|
||||
|
||||
def down
|
||||
raise AccessError unless @category.can_update? cuser
|
||||
@category.move_down(["domain = ?", @category.domain], "sort")
|
||||
redirect_to :categories
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @category.can_destroy? cuser
|
||||
@category.destroy
|
||||
redirect_to :categories
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_category
|
||||
@category = Category.find params[:id]
|
||||
end
|
||||
end
|
73
app/controllers/challenges_controller.rb
Normal file
73
app/controllers/challenges_controller.rb
Normal file
|
@ -0,0 +1,73 @@
|
|||
class ChallengesController < ApplicationController
|
||||
before_filter :get_challenge, :only => ['show', 'edit', 'update', 'destroy']
|
||||
|
||||
def index
|
||||
@challenges = Challenge.all
|
||||
end
|
||||
|
||||
def show
|
||||
return_here
|
||||
end
|
||||
|
||||
def refresh
|
||||
Challenge.past.pending.each do |c|
|
||||
c.destroy
|
||||
end
|
||||
|
||||
render :text => t(:challenges_cleared)
|
||||
end
|
||||
|
||||
def new
|
||||
@challenge = Challenge.new
|
||||
@challenge.user = cuser
|
||||
@challenge.contester2 = Contester.active.find params[:id]
|
||||
@challenge.get_contester1
|
||||
raise AccessError unless @challenge.can_create? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@challenge = Challenge.new params[:challenge]
|
||||
@challenge.user = cuser
|
||||
raise AccessError unless @challenge.can_create? cuser
|
||||
|
||||
if @challenge.valid? and @challenge.save
|
||||
flash[:notice] = t(:challenges_create)
|
||||
redirect_to @challenge
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@challenge = Challenge.find params[:id]
|
||||
raise AccessError unless @challenge.can_update? cuser
|
||||
case params[:commit]
|
||||
when "Accept"
|
||||
@challenge.status = Challenge::STATUS_ACCEPTED
|
||||
when "Default time"
|
||||
@challenge.status = Challenge::STATUS_DEFAULT
|
||||
when "Forfeit"
|
||||
@challenge.status = Challenge::STATUS_FORFEIT
|
||||
when "Decline"
|
||||
@challenge.status = Challenge::STATUS_DECLINED
|
||||
end
|
||||
|
||||
if @challenge.update_attributes params[:challenge]
|
||||
flash[:notice] = t(:challenges_update)
|
||||
end
|
||||
|
||||
render :action => "show"
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @challenge.can_destroy? cuser
|
||||
@challenge.destroy
|
||||
return_to
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_challenge
|
||||
@challenge = Challenge.find params[:id]
|
||||
end
|
||||
end
|
55
app/controllers/comments_controller.rb
Normal file
55
app/controllers/comments_controller.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
class CommentsController < ApplicationController
|
||||
before_filter :get_comment, :only => [:raw, 'edit', 'update', 'destroy']
|
||||
respond_to :html, :js
|
||||
|
||||
def index
|
||||
@comments = Comment.recent.filtered
|
||||
end
|
||||
|
||||
def show
|
||||
@comments = Comment.recent5.all :conditions => {:commentable_id => params[:id2], :commentable_type => params[:id]}
|
||||
render :partial => 'list', :layout => false
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @comment.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@comment = Comment.new params[:comment]
|
||||
@comment.user = cuser
|
||||
raise AccessError unless @comment.can_create? cuser
|
||||
|
||||
respond_to do |format|
|
||||
if @comment.save
|
||||
flash[:notice] = t(:comments_create)
|
||||
format.js { render }
|
||||
else
|
||||
flash[:error] = t(:comments_invalid) + @comment.errors.full_messages.to_s
|
||||
format.html { redirect_to(:back)}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @comment.can_update? cuser
|
||||
if @comment.update_attributes params[:comment]
|
||||
flash[:notice] = t(:comments_update)
|
||||
return_to
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @comment.can_destroy? cuser
|
||||
@comment.destroy
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_comment
|
||||
@comment = Comment.find params[:id]
|
||||
end
|
||||
end
|
62
app/controllers/contesters_controller.rb
Normal file
62
app/controllers/contesters_controller.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
class ContestersController < ApplicationController
|
||||
before_filter :get_contester, :only => ['show', 'edit', 'update', :recover, :destroy, :recalc]
|
||||
|
||||
def show
|
||||
@matches = Match.future.unfinished.ordered.of_contester @contester
|
||||
@results = Match.finished.ordered.of_contester @contester
|
||||
|
||||
raise AccessError unless @contester and @contester.contest and @contester.team
|
||||
|
||||
if @contester.contest.status == Contest::STATUS_CLOSED
|
||||
@members = @contester.team.teamers.distinct.ordered
|
||||
else
|
||||
@members = @contester.team.teamers.active.distinct.ordered
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @contester.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@contester = Contester.new params[:contester]
|
||||
@contester.user = cuser
|
||||
raise AccessError unless @contester.can_create? cuser
|
||||
|
||||
if @contester.save
|
||||
flash[:notice] = t(:contests_join)
|
||||
redirect_to contest_path(@contester.contest_id)
|
||||
else
|
||||
flash[:error] = t(:errors) + @contester.errors.full_messages.to_s
|
||||
redirect_to_back
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @contester.can_update? cuser
|
||||
if @contester.update_attributes params[:contester]
|
||||
flash[:notice] = t(:contests_contester_update)
|
||||
redirect_to @contester
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def recover
|
||||
raise AccessError unless @contester.can_destroy? cuser
|
||||
@contester.recover
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @contester.can_destroy? cuser
|
||||
@contester.destroy
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_contester
|
||||
@contester = Contester.find params[:id]
|
||||
end
|
||||
end
|
110
app/controllers/contests_controller.rb
Normal file
110
app/controllers/contests_controller.rb
Normal file
|
@ -0,0 +1,110 @@
|
|||
class ContestsController < ApplicationController
|
||||
before_filter :get_contest, :only => ['show', 'edit', 'update', 'destroy', 'del_map', 'scores', 'recalc']
|
||||
|
||||
def index
|
||||
#@contests = Contest.all
|
||||
@contests_active = Contest.active
|
||||
@contests_inactive = Contest.inactive
|
||||
end
|
||||
|
||||
def historical
|
||||
case params[:id]
|
||||
when "NS1"
|
||||
@contests = Contest.with_contesters.ordered.where ["name LIKE ? OR name LIKE ?", "S%:%", "%Night%"]
|
||||
else
|
||||
@contests = Contest.with_contesters.ordered.where ["id > ?", "113"]
|
||||
end
|
||||
end
|
||||
|
||||
def current
|
||||
@contests = Contest.active
|
||||
end
|
||||
|
||||
|
||||
def show
|
||||
# TODO
|
||||
# @friendly = cuser.active_contesters.of_contest(@contest).active.first if cuser
|
||||
end
|
||||
|
||||
def scores
|
||||
raise AccessError unless @contest.contest_type == Contest::TYPE_LADDER
|
||||
@friendly = params[:friendly] ? @contest.contesters.find(params[:friendly]) : @contest.contesters.first
|
||||
@rounds = [@contest.modulus_even, @contest.modulus_3to1, @contest.modulus_4to0]
|
||||
@rounds.each_index do |key|
|
||||
if params["rounds"] and params["rounds"]["#{key}"]
|
||||
@rounds[key] = params["rounds"]["#{key}"].to_f
|
||||
end
|
||||
end
|
||||
@weight = params[:weight] ? params[:weight].to_f : @contest.weight
|
||||
end
|
||||
|
||||
def recalc
|
||||
@contest.recalculate
|
||||
render :text => t(:score_recalc), :layout => true
|
||||
end
|
||||
|
||||
def new
|
||||
@contest = Contest.new
|
||||
raise AccessError unless @contest.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @contest.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@contest = Contest.new params[:contest]
|
||||
raise AccessError unless @contest.can_create? cuser
|
||||
|
||||
if @contest.save
|
||||
flash[:notice] = t(:contests_create)
|
||||
redirect_to @contest
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @contest.can_update? cuser
|
||||
if params[:commit] == "Save"
|
||||
if @contest.update_attributes(params[:contest])
|
||||
flash[:notice] = t(:contests_update)
|
||||
redirect_to @contest
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
elsif params[:commit] == "Add map"
|
||||
@contest.maps << Map.find(params[:map])
|
||||
render :action => "edit"
|
||||
elsif params[:commit] == "Add team"
|
||||
contester = Contester.new
|
||||
contester.team = Team.find params[:team]
|
||||
contester.contest = @contest
|
||||
contester.active = true
|
||||
if contester.valid?
|
||||
contester.save(false)
|
||||
else
|
||||
@contest.errors.add_to_base contester.errors.full_messages.to_s
|
||||
end
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def del_map
|
||||
raise AccessError unless @contest.can_update? cuser
|
||||
@contest.maps.delete(Map.find(params[:id2]))
|
||||
render :action => "edit"
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @contest.can_destroy? cuser
|
||||
@contest.destroy
|
||||
redirect_to contests_url
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_contest
|
||||
@contest = Contest.find params[:id]
|
||||
end
|
||||
end
|
105
app/controllers/data_files_controller.rb
Normal file
105
app/controllers/data_files_controller.rb
Normal file
|
@ -0,0 +1,105 @@
|
|||
class DataFilesController < ApplicationController
|
||||
before_filter :get_file, :only => ['show', 'edit', 'update', 'destroy', 'rate', :addFile, :delFile]
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def admin
|
||||
raise AccessError unless cuser and cuser.admin?
|
||||
@files = []
|
||||
DataFile.all.each do |f|
|
||||
@files << f unless File.exists?(f.path)
|
||||
end
|
||||
@movies = []
|
||||
DataFile.movies.each do |f|
|
||||
@movies << f unless f.movie or f.preview or (f.related and f.related.movie)
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@file = DataFile.new
|
||||
@file.directory = Directory.find params[:id]
|
||||
raise AccessError unless @file.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @file.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@file = DataFile.new params[:data_file]
|
||||
@file.size = 0
|
||||
raise AccessError unless @file.can_create? cuser
|
||||
|
||||
if @file.save
|
||||
flash[:notice] = t(:files_create)
|
||||
if @file.article
|
||||
redirect_to @file.article
|
||||
elsif @file.movie
|
||||
redirect_to @file.movie
|
||||
else
|
||||
redirect_to @file
|
||||
end
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @file.can_update? cuser
|
||||
if @file.update_attributes params[:data_file]
|
||||
flash[:notice] = t(:files_update)
|
||||
redirect_to(@file)
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def addFile
|
||||
raise AccessError unless @file.can_update? cuser
|
||||
@related = @file.directory.files.not(@file).find params[:data_file][:related_id]
|
||||
@related.related = @file
|
||||
@related.save
|
||||
redirect_to edit_data_file_url(@file)
|
||||
end
|
||||
|
||||
def delFile
|
||||
raise AccessError unless @file.can_update? cuser
|
||||
@related = @file.related_files.first params[:related_id]
|
||||
@related.related = nil
|
||||
@related.save
|
||||
redirect_to edit_data_file_url(@file)
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @file.can_destroy? cuser
|
||||
@file.destroy
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def rate
|
||||
raise AccessError unless cuser
|
||||
if params[:id2].to_i > 0 and params[:id2].to_i <= 5
|
||||
@file.rate_it(params[:id2], cuser.id)
|
||||
end
|
||||
head :ok
|
||||
end
|
||||
|
||||
def trash
|
||||
raise AccessError unless cuser and cuser.admin?
|
||||
@result = ""
|
||||
DataFile.all.each do |file|
|
||||
unless File.exists?(file.path)
|
||||
file.destroy
|
||||
@result << file.to_s + "<br />"
|
||||
end
|
||||
end
|
||||
render :text => @result, :layout => true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_file
|
||||
@file = DataFile.find params[:id]
|
||||
end
|
||||
end
|
61
app/controllers/directories_controller.rb
Normal file
61
app/controllers/directories_controller.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
class DirectoriesController < ApplicationController
|
||||
before_filter :get_directory, :except => [:new, :create]
|
||||
|
||||
def show
|
||||
if @directory.hidden
|
||||
@files = @directory.files
|
||||
render :partial => "data_files/list", :layout => true
|
||||
else
|
||||
@directories = Directory.ordered.filtered.all :conditions => {:parent_id => 1}
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@directory = Directory.new
|
||||
@directory.parent = Directory.find params[:id]
|
||||
raise AccessError unless @directory.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @directory.can_update? cuser
|
||||
end
|
||||
|
||||
def refresh
|
||||
@directory.process_dir
|
||||
render :text => t(:directories_update)
|
||||
end
|
||||
|
||||
def create
|
||||
@directory = Directory.new params[:directory]
|
||||
raise AccessError unless @directory.can_create? cuser
|
||||
|
||||
if @directory.save
|
||||
flash[:notice] = t(:directories_create)
|
||||
redirect_to(@directory)
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @directory.can_update? cuser
|
||||
if @directory.update_attributes(params[:directory])
|
||||
flash[:notice] = t(:directories_update)
|
||||
redirect_to @directory
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @directory.can_destroy? cuser
|
||||
@directory.destroy
|
||||
redirect_to directories_url
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_directory
|
||||
@directory = Directory.find params[:id]
|
||||
end
|
||||
end
|
35
app/controllers/forumers_controller.rb
Normal file
35
app/controllers/forumers_controller.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
class ForumersController < ApplicationController
|
||||
def create
|
||||
@forumer = Forumer.new params[:forumer]
|
||||
raise AccessError unless @forumer.can_create? cuser
|
||||
|
||||
if @forumer.save
|
||||
flash[:notice] = t(:groups_added)
|
||||
else
|
||||
flash[:error] = @forumer.errors.full_messages.to_s
|
||||
end
|
||||
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def update
|
||||
@forumer = Forumer.find params[:id]
|
||||
raise AccessError unless @forumer.can_update? cuser
|
||||
|
||||
if @forumer.update_attributes params[:forumer]
|
||||
flash[:notice] = t(:groups_acl_update)
|
||||
else
|
||||
flash[:error] = @forumer.errors.full_messages.to_s
|
||||
end
|
||||
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def destroy
|
||||
@forumer = Forumer.find params[:id]
|
||||
raise AccessError unless @forumer.can_destroy? cuser
|
||||
|
||||
@forumer.destroy
|
||||
redirect_to_back
|
||||
end
|
||||
end
|
70
app/controllers/forums_controller.rb
Normal file
70
app/controllers/forums_controller.rb
Normal file
|
@ -0,0 +1,70 @@
|
|||
class ForumsController < ApplicationController
|
||||
before_filter :get_forum, :only => [:show, :edit, :update, :up, :down, :destroy]
|
||||
|
||||
def index
|
||||
@categories = Category.domain(Category::DOMAIN_FORUMS).ordered
|
||||
@nobody = true
|
||||
end
|
||||
|
||||
def show
|
||||
raise AccessError unless @forum.can_show? cuser
|
||||
@topics = @forum.topics.all
|
||||
@forum.read_by! cuser if cuser
|
||||
@nobody = true
|
||||
end
|
||||
|
||||
def new
|
||||
@forum = Forum.new
|
||||
raise AccessError unless @forum.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @forum.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@forum = Forum.new(params[:forum])
|
||||
raise AccessError unless @forum.can_create? cuser
|
||||
|
||||
if @forum.save
|
||||
flash[:notice] = t(:forums_create)
|
||||
redirect_to(@forum)
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @forum.can_update? cuser
|
||||
if @forum.update_attributes(params[:forum])
|
||||
flash[:notice] = t(:forums_update)
|
||||
redirect_to(@forum)
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def up
|
||||
raise AccessError unless @forum.can_update? cuser
|
||||
@forum.move_up :category_id => @forum.category.id
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def down
|
||||
raise AccessError unless @forum.can_update? cuser
|
||||
@forum.move_down :category_id => @forum.category.id
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @forum.can_destroy? cuser
|
||||
@forum.destroy
|
||||
redirect_to(forums_url)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_forum
|
||||
@forum = Forum.find(params[:id])
|
||||
end
|
||||
end
|
47
app/controllers/gatherers_controller.rb
Normal file
47
app/controllers/gatherers_controller.rb
Normal file
|
@ -0,0 +1,47 @@
|
|||
class GatherersController < ApplicationController
|
||||
before_filter :get_gatherer, :except => [:create]
|
||||
|
||||
def create
|
||||
Gather.transaction do
|
||||
Gatherer.transaction do
|
||||
@gatherer = Gatherer.new params[:gatherer]
|
||||
@gatherer.gather.lock!
|
||||
raise AccessError unless @gatherer.can_create? cuser, params[:gatherer]
|
||||
|
||||
if @gatherer.save
|
||||
flash[:notice] = t(:gathers_join)
|
||||
else
|
||||
flash[:error] = @gatherer.errors.full_messages.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
redirect_to @gatherer.gather
|
||||
end
|
||||
|
||||
def update
|
||||
@gatherer = Gatherer.find params[:gatherer][:id]
|
||||
raise AccessError unless @gatherer.can_update? cuser, params[:gatherer]
|
||||
|
||||
if @gatherer.update_attributes params[:gatherer]
|
||||
flash[:notice] = t(:gatherers_update)
|
||||
else
|
||||
flash[:error] = @gatherer.errors.full_messages.to_s
|
||||
end
|
||||
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @gatherer.can_destroy? cuser
|
||||
|
||||
@gatherer.destroy
|
||||
redirect_to @gatherer.gather
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_gatherer
|
||||
@gatherer = Gatherer.find params[:id]
|
||||
end
|
||||
end
|
75
app/controllers/gathers_controller.rb
Normal file
75
app/controllers/gathers_controller.rb
Normal file
|
@ -0,0 +1,75 @@
|
|||
class GathersController < ApplicationController
|
||||
before_filter :get_gather, :except => [:latest, :index, :create]
|
||||
respond_to :html, :js
|
||||
|
||||
def index
|
||||
@gathers = Gather.ordered.limit(50).all
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def latest
|
||||
@gather = Gather.last(params[:game])
|
||||
redirect_to @gather
|
||||
end
|
||||
|
||||
def edit
|
||||
@gather.admin = true
|
||||
end
|
||||
|
||||
def create
|
||||
@gather = Gather.new
|
||||
@gather.category_id = params[:gather][:category_id]
|
||||
raise AccessError unless @gather.can_create? cuser
|
||||
|
||||
if @gather.save
|
||||
flash[:notice] = t(:gather_create)
|
||||
end
|
||||
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def update
|
||||
@gather = Gather.basic.find(params[:id])
|
||||
raise AccessError unless @gather.can_update? cuser
|
||||
|
||||
Gatherer.transaction do
|
||||
Gather.transaction do
|
||||
if @gather.update_attributes params[:gather]
|
||||
flash[:notice] = 'Gather was successfully updated.'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
redirect_to @gather
|
||||
end
|
||||
|
||||
def pick
|
||||
@gatherer = @gather.gatherers.find(params[:player])
|
||||
raise AccessError unless @gatherer.can_update? cuser, params
|
||||
|
||||
Gatherer.transaction do
|
||||
Gather.transaction do
|
||||
if @gatherer.update_attribute :team, @gatherer.gather.turn
|
||||
flash[:notice] = t(:gathers_user_pick)
|
||||
else
|
||||
flash[:error] = @gatherer.errors.full_messages.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
redirect_to @gather
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_gather
|
||||
Gather.transaction do
|
||||
@gather = Gather.basic.find(params[:id], :lock => true)
|
||||
@gather.refresh cuser
|
||||
end
|
||||
|
||||
@gatherer = @gather.gatherers.of_user(cuser).first if cuser
|
||||
end
|
||||
end
|
35
app/controllers/groupers_controller.rb
Normal file
35
app/controllers/groupers_controller.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
class GroupersController < ApplicationController
|
||||
def create
|
||||
@grouper = Grouper.new params[:grouper]
|
||||
raise AccessError unless @grouper.can_create? cuser
|
||||
|
||||
if @grouper.save
|
||||
flash[:notice] = t(:groups_user_add)
|
||||
else
|
||||
flash[:error] = @grouper.errors.full_messages.to_s
|
||||
end
|
||||
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def update
|
||||
@grouper = Grouper.find params[:id]
|
||||
raise AccessError unless @grouper.can_update? cuser
|
||||
|
||||
if @grouper.update_attributes params[:grouper]
|
||||
flash[:notice] = t(:groups_user_update)
|
||||
else
|
||||
flash[:error] = @grouper.errors.full_messages.to_s
|
||||
end
|
||||
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def destroy
|
||||
@grouper = Grouper.find params[:id]
|
||||
raise AccessError unless @grouper.can_destroy? cuser
|
||||
|
||||
@grouper.destroy
|
||||
redirect_to_back
|
||||
end
|
||||
end
|
71
app/controllers/groups_controller.rb
Normal file
71
app/controllers/groups_controller.rb
Normal file
|
@ -0,0 +1,71 @@
|
|||
class GroupsController < ApplicationController
|
||||
before_filter :get_group, :except => [:index, :new, :create]
|
||||
|
||||
def index
|
||||
@groups = Group.all
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def new
|
||||
@group = Group.new
|
||||
raise AccessError unless @group.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
@group.users.all
|
||||
raise AccessError unless @group.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@group = Group.new params[:group]
|
||||
@group.founder = cuser
|
||||
raise AccessError unless @group.can_create? cuser
|
||||
if @group.save
|
||||
flash[:notice] = t(:groups_create)
|
||||
redirect_to @group
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @group.can_update? cuser
|
||||
if @group.update_attributes params[:group]
|
||||
flash[:notice] = t(:groups_update)
|
||||
redirect_to @group
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @group.can_destroy? cuser
|
||||
@group.destroy
|
||||
redirect_to groups_url
|
||||
end
|
||||
|
||||
def addUser
|
||||
@user = User.first :conditions => {:username => params[:username]}
|
||||
raise AccessError unless @group.can_update? cuser
|
||||
raise Error, t(:duplicate_user) if @group.users.include? @user
|
||||
|
||||
@group.users << @user if @user
|
||||
redirect_to edit_group_url(@group, :groupTab => "groupTabMembers")
|
||||
end
|
||||
|
||||
def delUser
|
||||
@user = User.find params[:id2]
|
||||
raise AccessError unless @group.can_update? cuser
|
||||
|
||||
@group.users.delete @user
|
||||
redirect_to edit_group_url(@group, :groupTab => "groupTabMembers")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_group
|
||||
@group = Group.find params[:id]
|
||||
end
|
||||
end
|
72
app/controllers/issues_controller.rb
Normal file
72
app/controllers/issues_controller.rb
Normal file
|
@ -0,0 +1,72 @@
|
|||
class IssuesController < ApplicationController
|
||||
before_filter :get_issue, :only => [:show, :edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
raise AccessError unless cuser and cuser.admin?
|
||||
|
||||
sort = case params['sort']
|
||||
when "title" then "title"
|
||||
when "status" then "status"
|
||||
when "assigned" then "assigned_id"
|
||||
when "category" then "category_id"
|
||||
else "created_at DESC"
|
||||
end
|
||||
|
||||
@open = Issue.with_status(Issue::STATUS_OPEN).all :order => sort
|
||||
@solved = Issue.with_status(Issue::STATUS_SOLVED).all :order => sort
|
||||
@rejected = Issue.with_status(Issue::STATUS_REJECTED).all :order => sort
|
||||
end
|
||||
|
||||
def show
|
||||
raise AccessError unless @issue.can_show? cuser
|
||||
@issue.read_by! cuser
|
||||
end
|
||||
|
||||
def new
|
||||
@issue = Issue.new
|
||||
raise AccessError unless @issue.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @issue.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@issue = Issue.new(params[:issue])
|
||||
@issue.author = cuser if cuser
|
||||
raise AccessError unless @issue.can_create? cuser
|
||||
|
||||
if @issue.save
|
||||
flash[:notice] = t(:issues_create)
|
||||
if cuser
|
||||
redirect_to(@issue)
|
||||
else
|
||||
redirect_to_home
|
||||
end
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @issue.can_update? cuser
|
||||
if @issue.update_attributes(params[:issue])
|
||||
flash[:notice] = t(:issues_update)
|
||||
redirect_to(@issue)
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @issue.can_destroy? cuser
|
||||
@issue.destroy
|
||||
redirect_to(issues_url)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_issue
|
||||
@issue = Issue.find params[:id]
|
||||
end
|
||||
end
|
22
app/controllers/locks_controller.rb
Normal file
22
app/controllers/locks_controller.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
class LocksController < ApplicationController
|
||||
def create
|
||||
@lock = Lock.new params[:lock]
|
||||
raise AccessError unless @lock.can_create? cuser
|
||||
|
||||
if @lock.save
|
||||
flash[:notice] = t(:topics_locked)
|
||||
else
|
||||
flash[:error] = @lock.errors.full_messages.to_s
|
||||
end
|
||||
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def destroy
|
||||
@lock = Lock.find params[:id]
|
||||
raise AccessError unless @lock.can_destroy? cuser
|
||||
|
||||
@lock.destroy
|
||||
redirect_to_back
|
||||
end
|
||||
end
|
85
app/controllers/log_events_controller.rb
Normal file
85
app/controllers/log_events_controller.rb
Normal file
|
@ -0,0 +1,85 @@
|
|||
class LogEventsController < ApplicationController
|
||||
# GET /log_events
|
||||
# GET /log_events.xml
|
||||
def index
|
||||
@log_events = LogEvent.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.xml { render :xml => @log_events }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /log_events/1
|
||||
# GET /log_events/1.xml
|
||||
def show
|
||||
@log_event = LogEvent.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.xml { render :xml => @log_event }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /log_events/new
|
||||
# GET /log_events/new.xml
|
||||
def new
|
||||
@log_event = LogEvent.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.xml { render :xml => @log_event }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /log_events/1/edit
|
||||
def edit
|
||||
@log_event = LogEvent.find(params[:id])
|
||||
end
|
||||
|
||||
# POST /log_events
|
||||
# POST /log_events.xml
|
||||
def create
|
||||
@log_event = LogEvent.new(params[:log_event])
|
||||
|
||||
respond_to do |format|
|
||||
if @log_event.save
|
||||
flash[:notice] = t(:logevent_create)
|
||||
format.html { redirect_to(@log_event) }
|
||||
format.xml { render :xml => @log_event, :status => :created, :location => @log_event }
|
||||
else
|
||||
format.html { render :action => "new" }
|
||||
format.xml { render :xml => @log_event.errors, :status => :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /log_events/1
|
||||
# PUT /log_events/1.xml
|
||||
def update
|
||||
@log_event = LogEvent.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @log_event.update_attributes(params[:log_event])
|
||||
flash[:notice] = t(:logevent_update)
|
||||
format.html { redirect_to(@log_event) }
|
||||
format.xml { head :ok }
|
||||
else
|
||||
format.html { render :action => "edit" }
|
||||
format.xml { render :xml => @log_event.errors, :status => :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /log_events/1
|
||||
# DELETE /log_events/1.xml
|
||||
def destroy
|
||||
@log_event = LogEvent.find(params[:id])
|
||||
@log_event.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to(log_events_url) }
|
||||
format.xml { head :ok }
|
||||
end
|
||||
end
|
||||
end
|
42
app/controllers/log_files_controller.rb
Normal file
42
app/controllers/log_files_controller.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
class LogFilesController < ApplicationController
|
||||
def index
|
||||
LogFile.process
|
||||
render :text => "Ok"
|
||||
end
|
||||
|
||||
def handle
|
||||
LogFile.find(params[:id]).deal
|
||||
render :text => "Ok"
|
||||
end
|
||||
|
||||
def refresh
|
||||
LogFile.unhandled.each do |lf|
|
||||
lf.deal
|
||||
end
|
||||
end
|
||||
|
||||
def fix
|
||||
Rounder.find_in_batches(:batch_size => 100) do |rounders|
|
||||
rounders.each do |r|
|
||||
r.team_id = nil
|
||||
if r.user and t = Teamer.historic(r.user, r.round.start).first
|
||||
r.team_id = t.team_id
|
||||
end
|
||||
r.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pix
|
||||
Round.all.each do |r|
|
||||
r.team1_id = nil
|
||||
r.team2_id = nil
|
||||
[1, 2].each do |team|
|
||||
if s = r.rounders.team(team).stats.first
|
||||
r["team#{team}_id"] = s["team_id"]
|
||||
end
|
||||
end
|
||||
r.save
|
||||
end
|
||||
end
|
||||
end
|
53
app/controllers/maps_controller.rb
Normal file
53
app/controllers/maps_controller.rb
Normal file
|
@ -0,0 +1,53 @@
|
|||
class MapsController < ApplicationController
|
||||
before_filter :get_map, :only => [:show, :edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@maps = Map.basic
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def new
|
||||
@map = Map.new
|
||||
raise AccessError unless @map.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @map.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@map = Map.new params[:map]
|
||||
raise AccessError unless @map.can_create? cuser
|
||||
|
||||
if @map.save
|
||||
flash[:notice] = t(:maps_create)
|
||||
redirect_to @map
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @map.can_update? cuser
|
||||
if @map.update_attributes(params[:map])
|
||||
flash[:notice] = t(:maps_update)
|
||||
redirect_to @map
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @map.can_destroy? cuser
|
||||
@map.destroy
|
||||
redirect_to(maps_url)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_map
|
||||
@map = Map.find params[:id]
|
||||
end
|
||||
end
|
105
app/controllers/matches_controller.rb
Normal file
105
app/controllers/matches_controller.rb
Normal file
|
@ -0,0 +1,105 @@
|
|||
class MatchesController < ApplicationController
|
||||
before_filter :get_match, :except => [:index, :new, :create]
|
||||
|
||||
def index
|
||||
@matches = Match.active
|
||||
end
|
||||
|
||||
def show
|
||||
@ownpred = @match.predictions.first :conditions => {:user_id => cuser.id} if cuser
|
||||
@newpred = @match.predictions.build
|
||||
end
|
||||
|
||||
def new
|
||||
@match = Match.new
|
||||
@match.contest = Contest.find params[:id]
|
||||
raise AccessError unless @match.can_create? cuser
|
||||
end
|
||||
|
||||
def extra
|
||||
end
|
||||
|
||||
def score
|
||||
raise AccessError unless @match.can_update? cuser, [:matchers_attributes]
|
||||
@contester = @match.contester1.team.is_leader?(cuser) ? @match.contester1 : @match.contester2
|
||||
@n = 0
|
||||
end
|
||||
|
||||
def ref
|
||||
raise AccessError unless @match.can_update? cuser, [:report]
|
||||
@n = 0
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @match.can_update? cuser, [:contester1_id]
|
||||
end
|
||||
|
||||
def create
|
||||
@match = Match.new params[:match]
|
||||
raise AccessError unless @match.can_create? cuser
|
||||
|
||||
if @match.save
|
||||
flash[:notice] = t(:matches_create)
|
||||
redirect_to :controller => "contests", :action => "edit", :id => @match.contest
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @match.can_update? cuser, params[:match]
|
||||
if params[:match][:matchers_attributes]
|
||||
params[:match][:matchers_attributes].each do |key, matcher|
|
||||
matcher['_destroy'] = matcher['_destroy'] == "keep" ? false : true
|
||||
if matcher['user_id'] == ""
|
||||
params[:match][:matchers_attributes].delete key
|
||||
elsif matcher['user_id'].to_i == 0
|
||||
matcher['user_id'] = User.find_by_username(matcher['user_id']).id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if @match.update_attributes params[:match]
|
||||
respond_to do |format|
|
||||
format.xml { head :ok }
|
||||
format.html do
|
||||
flash[:notice] = t(:matches_update)
|
||||
#redirect_to_back
|
||||
redirect_to @match
|
||||
end
|
||||
end
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def hltv
|
||||
raise AccessError unless @match.can_update? cuser, [:hltv]
|
||||
|
||||
if params[:commit].include? t(:hltv_send)
|
||||
@match.hltv_record params[:addr], params[:pwd]
|
||||
flash[:notice] = t(:hltv_recording)
|
||||
elsif params[:commit].include? t(:hltv_move)
|
||||
sleep(90) if params[:wait] == "1"
|
||||
@match.hltv_move params[:addr], params[:pwd]
|
||||
flash[:notice] = t(:hltv_moved)
|
||||
elsif params[:commit].include? t(:hltv_stop)
|
||||
sleep(90) if params[:wait] == "1"
|
||||
@match.hltv_stop
|
||||
flash[:notice] = t(:hltv_stopped)
|
||||
end
|
||||
redirect_to :action => "show"
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @match.can_destroy? cuser
|
||||
@match.destroy
|
||||
redirect_to :controller => "contests", :action => "edit", :id => @match.contest
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_match
|
||||
@match = Match.find params[:id]
|
||||
end
|
||||
end
|
49
app/controllers/messages_controller.rb
Normal file
49
app/controllers/messages_controller.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
class MessagesController < ApplicationController
|
||||
before_filter :get_message, :only => [:show, :edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
raise AccessError unless cuser
|
||||
end
|
||||
|
||||
def show
|
||||
raise AccessError unless @message.can_show? cuser
|
||||
@message.read_by! cuser
|
||||
@messages = @message.thread
|
||||
end
|
||||
|
||||
def new
|
||||
@message = Message.new
|
||||
raise AccessError unless @message.can_create? cuser
|
||||
|
||||
case params[:id]
|
||||
when "User"
|
||||
@message.recipient = User.find(params[:id2])
|
||||
when "Team"
|
||||
@message.recipient = Team.find(params[:id2])
|
||||
when "Group"
|
||||
@message.recipient = Group.find(params[:id2])
|
||||
else
|
||||
raise Error, "Illegible recipient"
|
||||
end
|
||||
@message.title = params[:title]
|
||||
end
|
||||
|
||||
def create
|
||||
@message = Message.new(params[:message])
|
||||
@message.sender = @message.sender_raw == "" ? cuser : cuser.active_teams.find(@message.sender_raw)
|
||||
raise AccessError unless @message.can_create? cuser
|
||||
|
||||
if @message.save
|
||||
flash[:notice] = t(:message_create)
|
||||
redirect_to(@message)
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_message
|
||||
@message = Message.find(params[:id])
|
||||
end
|
||||
end
|
97
app/controllers/movies_controller.rb
Normal file
97
app/controllers/movies_controller.rb
Normal file
|
@ -0,0 +1,97 @@
|
|||
class MoviesController < ApplicationController
|
||||
before_filter :get_movie, :except => [:index, :new, :create]
|
||||
|
||||
def index
|
||||
@movies = []
|
||||
order = case params[:order]
|
||||
when "date" then "data_files.created_at DESC"
|
||||
when "author" then "users.username ASC"
|
||||
when "ratings" then "total_ratings DESC"
|
||||
else "total_ratings DESC"
|
||||
end
|
||||
|
||||
if params[:filter]
|
||||
Movie.index(order).each do |movie|
|
||||
if movie.file and movie.file.average_rating_round >= params[:filter].to_i
|
||||
@movies << movie
|
||||
end
|
||||
end
|
||||
else
|
||||
@movies = Movie.index(order)
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@movie.read_by! cuser if cuser
|
||||
@movie.record_view_count(request.remote_ip, cuser.nil?)
|
||||
redirect_to @movie.file.related if @movie.file and @movie.file.related
|
||||
end
|
||||
|
||||
def refresh
|
||||
@movie.update_status
|
||||
end
|
||||
|
||||
def new
|
||||
@movie = Movie.new
|
||||
raise AccessError unless @movie.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @movie.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@movie = Movie.new(params[:movie])
|
||||
raise AccessError unless @movie.can_create? cuser
|
||||
|
||||
if @movie.save
|
||||
flash[:notice] = t(:movies_create)
|
||||
redirect_to(@movie)
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @movie.can_update? cuser
|
||||
|
||||
if @movie.update_attributes(params[:movie])
|
||||
flash[:notice] = t(:movies_update)
|
||||
redirect_to(@movie)
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def preview
|
||||
raise AccessError unless @movie.can_update? cuser
|
||||
x = params[:x].to_i <= 1280 ? params[:x].to_i : 800
|
||||
y = params[:y].to_i <= 720 ? params[:y].to_i : 600
|
||||
render :text => t(:executed) + "<br />" + @movie.make_preview(x, y), :layout => true
|
||||
end
|
||||
|
||||
def snapshot
|
||||
raise AccessError unless @movie.can_update? cuser
|
||||
secs = params[:secs].to_i > 0 ? params[:secs].to_i : 5
|
||||
render :text => t(:executed) + "<br />" + @movie.make_snapshot(secs), :layout => true
|
||||
end
|
||||
|
||||
def download
|
||||
raise AccessError unless cuser.admin?
|
||||
@movie.stream_ip = params[:ip]
|
||||
@movie.stream_port = params[:port]
|
||||
render :text => t(:executed) + "<br />" + @movie.make_stream, :layout => true
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @movie.can_destroy? cuser
|
||||
@movie.destroy
|
||||
redirect_to(movies_url)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_movie
|
||||
@movie = Movie.find(params[:id])
|
||||
end
|
||||
end
|
43
app/controllers/options_controller.rb
Normal file
43
app/controllers/options_controller.rb
Normal file
|
@ -0,0 +1,43 @@
|
|||
class PollsController < ApplicationController
|
||||
before_filter :get_poll, :except => [:index, :new, :create]
|
||||
respond_to :js
|
||||
|
||||
def add
|
||||
end
|
||||
|
||||
def create
|
||||
@poll = Poll.new params[:poll]
|
||||
@poll.user = cuser
|
||||
raise AccessError unless @poll.can_create? cuser
|
||||
|
||||
if @poll.save
|
||||
flash[:notice] = t(:polls_create)
|
||||
redirect_to @poll
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @poll.can_update? cuser
|
||||
|
||||
if @poll.update_attributes params[:poll]
|
||||
flash[:notice] = t(:polls_update)
|
||||
redirect_to @poll
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @poll.can_destroy? cuser
|
||||
@poll.destroy
|
||||
redirect_to polls_url
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_poll
|
||||
@poll = Poll.find params[:id]
|
||||
end
|
||||
end
|
128
app/controllers/plugin_controller.rb
Normal file
128
app/controllers/plugin_controller.rb
Normal file
|
@ -0,0 +1,128 @@
|
|||
class PluginController < ApplicationController
|
||||
def esi
|
||||
buffer = []
|
||||
out = []
|
||||
buffer << Time.now.utc.to_i
|
||||
buffer << "1.2"
|
||||
buffer << params[:ch] ? params[:ch] : ""
|
||||
out << "#ESI#"
|
||||
out << Verification.verify(buffer.join)
|
||||
out << buffer.join("\r")
|
||||
render_out out
|
||||
end
|
||||
|
||||
def user
|
||||
buffer = []
|
||||
out = []
|
||||
|
||||
if ban = Ban.first(:conditions => ["expiry > UTC_TIMESTAMP() AND steamid = ? AND ban_type = ?", params[:id], Ban::TYPE_SERVER])
|
||||
out << "#USER#"
|
||||
out << "BANNED"
|
||||
out << ban.expiry.utc.to_i
|
||||
out << ban.reason
|
||||
out << "\r\r\r\r\r\r\r"
|
||||
elsif user = User.first(:conditions => {:steamid => params[:id]})
|
||||
teamer = (user.team ? user.teamers.active.of_team(user.team).first : nil)
|
||||
icon = 0
|
||||
rank = "User"
|
||||
if Group.find(Group::DONORS).users.exists?(user)
|
||||
rank = "Donor"
|
||||
icon = icon | 1
|
||||
end
|
||||
if Group.find(Group::CHAMPIONS).users.exists?(user)
|
||||
icon = icon | 2
|
||||
end
|
||||
if user.ref?
|
||||
rank = "Referee"
|
||||
icon = icon | 4
|
||||
end
|
||||
if user.admin?
|
||||
rank = "Admin"
|
||||
icon = icon | 8
|
||||
end
|
||||
|
||||
buffer << user.steamid
|
||||
buffer << user.username
|
||||
buffer << user.lastip
|
||||
buffer << (user.team ? Verification.uncrap(user.team.to_s) : "No Team")
|
||||
buffer << user.id
|
||||
buffer << user.team_id
|
||||
buffer << rank
|
||||
buffer << (teamer ? teamer.ranks[teamer.rank] : "")
|
||||
buffer << icon
|
||||
buffer << params[:ch] ? params[:ch] : ""
|
||||
buffer << (user.can_play? ? "1" : "0")
|
||||
|
||||
out << "#USER#"
|
||||
out << Verification.verify(buffer.join)
|
||||
out << buffer.join("\r")
|
||||
else
|
||||
out << "#FAIL#"
|
||||
end
|
||||
|
||||
render_out out
|
||||
end
|
||||
|
||||
#def admin
|
||||
# areq = AdminRequest.new
|
||||
# areq.addr = params[:addr]
|
||||
# areq.pwd = params[:pwd]
|
||||
# areq.msg = params[:msg]
|
||||
# areq.player = params[:player]
|
||||
# areq.user_id = params[:user]
|
||||
# areq.save!
|
||||
# render :text => "Ok"
|
||||
#end
|
||||
|
||||
def ban
|
||||
ban = Ban.new
|
||||
ban.steamid = params[:id]
|
||||
ban.ts = params[:ts]
|
||||
ban.sign = params[:sign]
|
||||
ban.expiry = DateTime.now.ago(-(params[:len].to_i*60))
|
||||
ban.addr = params[:addr]
|
||||
ban.reason = params[:reason]
|
||||
ban.ban_type = Ban::TYPE_SERVER
|
||||
ban.save!
|
||||
|
||||
render :text => "Ok"
|
||||
end
|
||||
|
||||
def hltv_req
|
||||
if params[:game].to_i > 0
|
||||
if match = Match.first(:conditions => {:id => params[:game]})
|
||||
match.hltv_record params[:addr], params[:pwd]
|
||||
hltv = match.hltv
|
||||
else
|
||||
render :text => t(:matches_notfound)
|
||||
end
|
||||
else
|
||||
hltv = Server.hltvs.active.unreserved_now.unreserved_hltv_around(DateTime.now).first unless hltv
|
||||
render :text => t(:hltv_notavailable) unless hltv
|
||||
|
||||
hltv.recording = params[:game]
|
||||
hltv.reservation = params[:addr]
|
||||
hltv.pwd = params[:pwd]
|
||||
hltv.save!
|
||||
end
|
||||
|
||||
render :text => t(:hltv_sent)
|
||||
end
|
||||
|
||||
def hltv_move
|
||||
Server.move params[:addr], params[:newaddr], params[:newpwd]
|
||||
render :text => t(:hltv_movedd) + params[:newaddr]
|
||||
end
|
||||
|
||||
def hltv_stop
|
||||
Server.stop params[:addr]
|
||||
render :text => t(:hltv_stopped)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_out out
|
||||
@text = out.join("\r")
|
||||
render :layout => false
|
||||
end
|
||||
end
|
56
app/controllers/polls_controller.rb
Normal file
56
app/controllers/polls_controller.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
class PollsController < ApplicationController
|
||||
before_filter :get_poll, :except => [:index, :new, :create]
|
||||
|
||||
def index
|
||||
@polls = Poll.all
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def new
|
||||
@poll = Poll.new
|
||||
@poll.options.build
|
||||
raise AccessError unless @poll.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @poll.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@poll = Poll.new params[:poll]
|
||||
@poll.user = cuser
|
||||
raise AccessError unless @poll.can_create? cuser
|
||||
|
||||
if @poll.save
|
||||
flash[:notice] = t(:polls_create)
|
||||
redirect_to @poll
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @poll.can_update? cuser
|
||||
|
||||
if @poll.update_attributes params[:poll]
|
||||
flash[:notice] = t(:polls_update)
|
||||
redirect_to @poll
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @poll.can_destroy? cuser
|
||||
@poll.destroy
|
||||
redirect_to polls_url
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_poll
|
||||
@poll = Poll.find params[:id]
|
||||
end
|
||||
end
|
72
app/controllers/posts_controller.rb
Normal file
72
app/controllers/posts_controller.rb
Normal file
|
@ -0,0 +1,72 @@
|
|||
class PostsController < ApplicationController
|
||||
before_filter :get_post, :except => [:new, :create]
|
||||
respond_to :html, :js
|
||||
|
||||
def quote
|
||||
raise AccessError unless @post.can_show? cuser
|
||||
end
|
||||
|
||||
def new
|
||||
@post = Post.new
|
||||
@post.topic = Topic.find(params[:id])
|
||||
raise AccessError unless @post.can_create? cuser
|
||||
render :layout => "forums"
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @post.can_update? cuser
|
||||
render :layout => "forums"
|
||||
end
|
||||
|
||||
def create
|
||||
@post = Post.new(params[:post])
|
||||
@post.user = cuser
|
||||
raise AccessError unless @post.can_create? cuser
|
||||
|
||||
respond_to do |format|
|
||||
if @post.save
|
||||
flash[:notice] = t(:posts_create)
|
||||
format.js { render }
|
||||
else
|
||||
flash[:error] = t(:posts_invalid) + @post.errors.full_messages.to_s
|
||||
format.html { return_to }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @post.can_update? cuser, params[:post]
|
||||
if @post.update_attributes(params[:post])
|
||||
flash[:notice] = t(:posts_update)
|
||||
redirect_to @post.topic
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def trash
|
||||
raise AccessError unless @post.can_destroy? cuser
|
||||
@post.trash
|
||||
if Topic.exists? @post.topic
|
||||
redirect_to @post.topic
|
||||
else
|
||||
redirect_to @post.topic.forum
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @post.can_destroy? cuser
|
||||
@post.destroy
|
||||
if Topic.exists? @post.topic
|
||||
redirect_to @post.topic
|
||||
else
|
||||
redirect_to @post.topic.forum
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_post
|
||||
@post = Post.find(params[:id])
|
||||
end
|
||||
end
|
15
app/controllers/predictions_controller.rb
Normal file
15
app/controllers/predictions_controller.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
class PredictionsController < ApplicationController
|
||||
def create
|
||||
@prediction = Prediction.new params[:prediction]
|
||||
@prediction.user = cuser
|
||||
raise AccessError unless @prediction.can_create? cuser
|
||||
|
||||
if @prediction.save
|
||||
flash[:notice] = t(:predictions_create)
|
||||
else
|
||||
flash[:error] = @prediction.errors.full_messages.to_s
|
||||
end
|
||||
|
||||
redirect_to @prediction.match
|
||||
end
|
||||
end
|
26
app/controllers/rounds_controller.rb
Normal file
26
app/controllers/rounds_controller.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
class RoundsController < ApplicationController
|
||||
def index
|
||||
sort = case params['sort']
|
||||
when "start" then "start"
|
||||
when "server" then "server_id"
|
||||
when "team1" then "team1_id"
|
||||
when "team2" then "team2_id"
|
||||
when "map" then "map_name"
|
||||
when "commander" then "commander_id"
|
||||
end
|
||||
|
||||
@rounds = Round.basic.paginate \
|
||||
:order => sort,
|
||||
:page => params[:page],
|
||||
:per_page => 30
|
||||
|
||||
if params[:ajax]
|
||||
render :partial => "list", :layout => false
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@round = Round.find(params[:id])
|
||||
end
|
||||
end
|
78
app/controllers/servers_controller.rb
Normal file
78
app/controllers/servers_controller.rb
Normal file
|
@ -0,0 +1,78 @@
|
|||
class ServersController < ApplicationController
|
||||
before_filter :get_server, :except => [:index, :refresh, :new, :create]
|
||||
|
||||
def refresh
|
||||
Server.refresh
|
||||
render :text => t(:servers_updated)
|
||||
end
|
||||
|
||||
def index
|
||||
@servers = Server.hlds.active.ordered.all :include => :user
|
||||
@ns2 = Server.ns2.active.ordered.all :include => :user
|
||||
@hltvs = Server.hltvs.active.ordered.all :include => :user
|
||||
@officials = Server.ns2.active.ordered.where ["name LIKE ?", "%NSL%"]
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def new
|
||||
@server = Server.new
|
||||
raise AccessError unless @server.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @server.can_update? cuser
|
||||
end
|
||||
|
||||
def admin
|
||||
@result = @server.execute params[:query] if params[:query]
|
||||
raise AccessError unless @server.can_update? cuser
|
||||
|
||||
if request.xhr?
|
||||
render :partial => "response", :layout => false
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@server = Server.new params[:server]
|
||||
@server.user = cuser
|
||||
raise AccessError unless @server.can_create? cuser
|
||||
|
||||
if @server.save
|
||||
flash[:notice] = t(:server_create)
|
||||
redirect_to @server
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @server.can_update? cuser
|
||||
|
||||
if @server.update_attributes params[:server]
|
||||
flash[:notice] = t(:server_update)
|
||||
redirect_to @server
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def default
|
||||
raise AccessError unless @server.can_update? cuser
|
||||
@server.default_record
|
||||
render :text => "Ok"
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @server.can_destroy? cuser
|
||||
@server.destroy
|
||||
redirect_to(servers_url)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_server
|
||||
@server = Server.find params[:id]
|
||||
end
|
||||
end
|
39
app/controllers/shoutmsgs_controller.rb
Normal file
39
app/controllers/shoutmsgs_controller.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
class ShoutmsgsController < ApplicationController
|
||||
respond_to :html, :js
|
||||
|
||||
def index
|
||||
@shoutmsgs = Shoutmsg.lastXXX.typebox
|
||||
end
|
||||
|
||||
def show
|
||||
if params[:id2]
|
||||
@shoutmsgs = Shoutmsg.recent.of_object(params[:id], params[:id2]).reverse
|
||||
else
|
||||
@shoutmsgs = Shoutmsg.recent.box
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@shoutmsg = Shoutmsg.new params[:shoutmsg]
|
||||
@shoutmsg.user = cuser
|
||||
raise AccessError unless @shoutmsg.can_create? cuser
|
||||
|
||||
unless @shoutmsg.save
|
||||
flash[:error] = t(:invalid_message)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@shoutmsg = Shoutmsg.find params[:id]
|
||||
raise AccessError unless @shoutmsg.can_destroy? cuser
|
||||
@shoutmsg.destroy
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def render_shoutmsgs shoutable_type = nil, shoutable_id = nil
|
||||
|
||||
end
|
||||
end
|
23
app/controllers/teamers_controller.rb
Normal file
23
app/controllers/teamers_controller.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
class TeamersController < ApplicationController
|
||||
def create
|
||||
@teamer = Teamer.new params[:teamer]
|
||||
raise AccessError unless @teamer.can_create? cuser, params[:teamer]
|
||||
@teamer.user = cuser unless cuser.admin?
|
||||
|
||||
if @teamer.save
|
||||
flash[:notice] = t(:applying_team) + @teamer.team.to_s
|
||||
else
|
||||
flash[:error] = @teamer.errors.full_messages.to_s
|
||||
end
|
||||
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
def destroy
|
||||
@teamer = Teamer.find params[:id]
|
||||
raise AccessError unless @teamer.can_destroy? cuser
|
||||
|
||||
@teamer.destroy
|
||||
redirect_to_back
|
||||
end
|
||||
end
|
72
app/controllers/teams_controller.rb
Normal file
72
app/controllers/teams_controller.rb
Normal file
|
@ -0,0 +1,72 @@
|
|||
class TeamsController < ApplicationController
|
||||
before_filter :get_team, :only => ['show', 'edit', 'update', 'destroy', 'recover']
|
||||
|
||||
def index
|
||||
@teams = Team.with_teamers_num(0).ordered
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def new
|
||||
@team = Team.new
|
||||
raise AccessError unless @team.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @team.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@team = Team.new params[:team]
|
||||
@team.founder = cuser
|
||||
raise AccessError unless @team.can_create? cuser
|
||||
|
||||
if @team.save
|
||||
flash[:notice] = t(:teams_create)
|
||||
redirect_to @team
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @team.can_update? cuser
|
||||
if @team.update_attributes params[:team]
|
||||
if params[:rank]
|
||||
@team.teamers.present.each do |member|
|
||||
rank = params[:rank]["#{member.id}"]
|
||||
if cuser.admin? or (rank.to_i <= cuser.teamers.active.of_team(@team).first.rank)
|
||||
if member.rank == Teamer::RANK_JOINER
|
||||
member.user.update_attribute :team, @team
|
||||
end
|
||||
member.update_attribute :rank, rank
|
||||
member.update_attribute :comment, params[:comment]["#{member.id}"]
|
||||
end
|
||||
end
|
||||
end
|
||||
flash[:notice] = t(:teams_update)
|
||||
redirect_to edit_team_path(@team)
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @team.can_destroy? cuser
|
||||
@team.destroy
|
||||
redirect_to(teams_url)
|
||||
end
|
||||
|
||||
def recover
|
||||
raise AccessError unless @team.can_destroy? cuser
|
||||
@team.recover
|
||||
redirect_to(teams_url)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_team
|
||||
@team = Team.find params[:id]
|
||||
end
|
||||
end
|
81
app/controllers/topics_controller.rb
Normal file
81
app/controllers/topics_controller.rb
Normal file
|
@ -0,0 +1,81 @@
|
|||
class TopicsController < ApplicationController
|
||||
before_filter :get_topic, :only => [:show, :reply, :edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
render :partial => true, :locals => {:page => params[:p].to_i}
|
||||
end
|
||||
|
||||
def show
|
||||
raise AccessError unless @topic.can_show? cuser
|
||||
@posts = @topic.posts.basic.paginate \
|
||||
:page => params[:page],
|
||||
:per_page => Topic::POSTS_PAGE
|
||||
|
||||
return_here
|
||||
@topic.record_view_count(request.remote_ip, cuser.nil?)
|
||||
@topic.read_by! cuser if cuser
|
||||
@topic.forum.read_by! cuser if cuser
|
||||
@newpost = Post.new
|
||||
@newpost.topic = @topic
|
||||
@newpost.user = cuser
|
||||
@lock = (@topic.lock ? @topic.lock : Lock.new(:lockable => @topic))
|
||||
render :layout => "forums"
|
||||
end
|
||||
|
||||
def reply
|
||||
@post = @topic.posts.build
|
||||
raise AccessError unless @post.can_create? cuser
|
||||
if request.xhr?
|
||||
render "quickreply", :layout => false
|
||||
else
|
||||
render :layout => "forums"
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@topic = Topic.new
|
||||
@topic.forum = Forum.find(params[:id])
|
||||
raise AccessError unless @topic.can_create? cuser
|
||||
render :layout => "forums"
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @topic.can_update? cuser
|
||||
render :layout => "forums"
|
||||
end
|
||||
|
||||
def create
|
||||
@topic = Topic.new(params[:topic])
|
||||
@topic.user = cuser
|
||||
raise AccessError unless @topic.can_create? cuser
|
||||
|
||||
if @topic.save
|
||||
flash[:notice] = t(:topics_create)
|
||||
redirect_to(@topic)
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @topic.can_update? cuser
|
||||
if @topic.update_attributes(params[:topic])
|
||||
flash[:notice] = t(:topics_update)
|
||||
redirect_to(@topic)
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @topic.can_destroy? cuser
|
||||
@topic.destroy
|
||||
redirect_to(topics_url)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_topic
|
||||
@topic = Topic.find(params[:id])
|
||||
end
|
||||
end
|
29
app/controllers/tweets_controller.rb
Normal file
29
app/controllers/tweets_controller.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
require 'rss/2.0'
|
||||
require 'open-uri'
|
||||
|
||||
class TweetsController < ApplicationController
|
||||
def index
|
||||
@tweets = Tweet.all :order => "created_at DESC"
|
||||
@nobody = true
|
||||
end
|
||||
|
||||
def show
|
||||
@tweet = Tweet.find(params[:id])
|
||||
end
|
||||
|
||||
def refresh
|
||||
open('http://twitter.com/statuses/user_timeline/16676427.rss') do |http|
|
||||
RSS::Parser.parse(http.read, false).items.each do |item|
|
||||
unless Tweet.first :conditions => {:link => item.link}
|
||||
tweet = Tweet.new
|
||||
tweet.link = item.link
|
||||
tweet.msg = item.title.gsub(/NS2: /, "")
|
||||
tweet.created_at = DateTime.parse item.pubDate.to_s
|
||||
tweet.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
render :text => t(:tweets_refresh)
|
||||
end
|
||||
end
|
130
app/controllers/users_controller.rb
Normal file
130
app/controllers/users_controller.rb
Normal file
|
@ -0,0 +1,130 @@
|
|||
class UsersController < ApplicationController
|
||||
before_filter :get_user, :only => [:show, :history, :popup, :agenda, :edit, :update, :destroy]
|
||||
respond_to :html, :js
|
||||
|
||||
def index
|
||||
@users = User.search(params[:search]).paginate(:per_page => 40, :page => params[:page])
|
||||
end
|
||||
|
||||
def show
|
||||
@page = "general"
|
||||
respond_to do |format|
|
||||
format.js do
|
||||
pages = ["general", "favorites", "computer", "articles", "movies", "teams", "matches", "predictions", "comments"]
|
||||
if pages.include?(params[:page])
|
||||
@page = params[:page]
|
||||
end
|
||||
end
|
||||
format.html {}
|
||||
end
|
||||
end
|
||||
|
||||
def agenda
|
||||
@teamer = Teamer.new
|
||||
@teamer.user = @user
|
||||
end
|
||||
|
||||
def history
|
||||
raise AccessError unless cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def popup
|
||||
render :layout => false
|
||||
end
|
||||
|
||||
def new
|
||||
@user = User.new
|
||||
@user.profile = Profile.new
|
||||
@user.lastip = request.env['REMOTE_ADDR']
|
||||
@user.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @user.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@user = User.new params[:user]
|
||||
@user.lastvisit = Date.today
|
||||
@user.lastip = request.env['REMOTE_ADDR']
|
||||
|
||||
raise AccessError unless @user.can_create? cuser
|
||||
|
||||
if @user.valid? and @user.save
|
||||
@user.profile = Profile.new
|
||||
@user.profile.user = @user
|
||||
@user.profile.save()
|
||||
redirect_to :action => :show, :id => @user.id
|
||||
save_session @user
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @user.can_update? cuser
|
||||
if @user.update_attributes params[:user]
|
||||
flash[:notice] = t(:users_update)
|
||||
redirect_to_back
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @user.can_destroy? cuser
|
||||
@user.destroy
|
||||
redirect_to users_url
|
||||
end
|
||||
|
||||
def login
|
||||
return unless request.post?
|
||||
|
||||
if u = User.authenticate(params[:login][:username], params[:login][:password])
|
||||
raise Error, t(:accounts_locked) if u.banned? Ban::TYPE_SITE
|
||||
|
||||
flash[:notice] = t(:login_successful)
|
||||
save_session u
|
||||
|
||||
if session[:return_to]
|
||||
return_to
|
||||
else
|
||||
redirect_to_back
|
||||
end
|
||||
else
|
||||
flash[:error] = t(:login_unsuccessful)
|
||||
redirect_to_back
|
||||
end
|
||||
end
|
||||
|
||||
def logout
|
||||
if request.post?
|
||||
session[:user] = nil
|
||||
flash[:notice] = t(:login_out)
|
||||
redirect_to :root
|
||||
end
|
||||
end
|
||||
|
||||
def forgot
|
||||
if request.post?
|
||||
if u = User.first(:conditions => {:username => params[:username], :email => params[:email]}) and u.send_new_password
|
||||
flash[:notice] = t(:passwords_sent)
|
||||
else
|
||||
flash[:error] = t(:incorrect_information)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_user
|
||||
@user = User.find(params[:id])
|
||||
end
|
||||
|
||||
def save_session user
|
||||
session[:user] = user.id
|
||||
user.lastip = request.ip
|
||||
user.lastvisit = DateTime.now
|
||||
user.save()
|
||||
end
|
||||
end
|
32
app/controllers/versions_controller.rb
Normal file
32
app/controllers/versions_controller.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
class VersionsController < ApplicationController
|
||||
before_filter :get_article
|
||||
|
||||
def index
|
||||
@versions = @article.versions
|
||||
render "articles/history"
|
||||
end
|
||||
|
||||
def show
|
||||
@version = @article.versions.find params[:id]
|
||||
@nobody = true
|
||||
render "articles/version"
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @article.can_update? cuser
|
||||
@version = @article.versions.find params[:id]
|
||||
@nobody = true
|
||||
|
||||
if @article.revert_to! @version.version
|
||||
flash[:notice] = t(:articles_revert, :version => @version.version)
|
||||
end
|
||||
|
||||
redirect_to @article
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_article
|
||||
@article = Article.find(params[:article_id])
|
||||
end
|
||||
end
|
13
app/controllers/votes_controller.rb
Normal file
13
app/controllers/votes_controller.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
class VotesController < ApplicationController
|
||||
def create
|
||||
@vote = Vote.new params[:vote]
|
||||
@vote.user = cuser
|
||||
raise AccessError unless @vote.can_create? cuser
|
||||
|
||||
if @vote.save
|
||||
flash[:notice] = t(:votes_success)
|
||||
end
|
||||
|
||||
redirect_to_back
|
||||
end
|
||||
end
|
48
app/controllers/weeks_controller.rb
Normal file
48
app/controllers/weeks_controller.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
class WeeksController < ApplicationController
|
||||
before_filter :get_week, :except => [:new, :create]
|
||||
|
||||
def new
|
||||
@week = Week.new
|
||||
@week.contest = Contest.find params[:id]
|
||||
raise AccessError unless @week.can_create? cuser
|
||||
end
|
||||
|
||||
def edit
|
||||
raise AccessError unless @week.can_update? cuser
|
||||
end
|
||||
|
||||
def create
|
||||
@week = Week.new(params[:week])
|
||||
raise AccessError unless @week.can_create? cuser
|
||||
|
||||
if @week.save
|
||||
flash[:notice] = t(:weeks_create)
|
||||
redirect_to @week.contest
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
raise AccessError unless @week.can_update? cuser
|
||||
|
||||
if @week.update_attributes(params[:week])
|
||||
flash[:notice] = t(:weeks_update)
|
||||
redirect_to @week.contest
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise AccessError unless @week.can_destroy? cuser
|
||||
@week.destroy
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_week
|
||||
@week = Week.find params[:id]
|
||||
end
|
||||
end
|
133
app/helpers/application_helper.rb
Normal file
133
app/helpers/application_helper.rb
Normal file
|
@ -0,0 +1,133 @@
|
|||
module ApplicationHelper
|
||||
def namelink model, length = nil
|
||||
return if model.nil?
|
||||
model = case model.class.to_s
|
||||
when "DataFile"
|
||||
model.movie ? model.movie : model
|
||||
when "Comment"
|
||||
model.commentable
|
||||
when "Post"
|
||||
model.topic
|
||||
else
|
||||
model
|
||||
end
|
||||
str = model.to_s
|
||||
if length and str.length > length
|
||||
link_to raw(str.to_s[0, length] + "..."), model
|
||||
else
|
||||
link_to raw(str), model
|
||||
end
|
||||
end
|
||||
|
||||
def shorten str, length
|
||||
if length and str and str.to_s.length > length
|
||||
str = str.to_s[0, length] + "..."
|
||||
end
|
||||
str
|
||||
end
|
||||
|
||||
def longtime time
|
||||
printtime time, "%d %B %y %H:%M"
|
||||
end
|
||||
|
||||
def shorttime time
|
||||
printtime time, "%d/%b/%y %H:%M"
|
||||
end
|
||||
|
||||
def shortdate time
|
||||
printtime time, "%d %b %y"
|
||||
end
|
||||
|
||||
def longdate time
|
||||
printtime time, "%d %B %Y"
|
||||
end
|
||||
|
||||
def printtime time, format
|
||||
return unless time
|
||||
out = ""
|
||||
out << '<span style="font-style: italic; ">'
|
||||
out << time.strftime(format)
|
||||
out << '</span>'
|
||||
raw out
|
||||
end
|
||||
|
||||
def cascade model, list
|
||||
out = ""
|
||||
|
||||
list.each do |element|
|
||||
name = key = element
|
||||
result = ""
|
||||
|
||||
if element.instance_of?(Array)
|
||||
name = element[0]
|
||||
key = element[1]
|
||||
end
|
||||
|
||||
if m = key.to_s.match(/^(.*)_b$/)
|
||||
name = m[1]
|
||||
key = m[1]
|
||||
end
|
||||
|
||||
str = eval("model.#{key}")
|
||||
next if str == "" or str.nil?
|
||||
|
||||
if model[key].instance_of?(Time)
|
||||
result << shorttime(str)
|
||||
elsif element.instance_of?(Symbol)
|
||||
result << namelink(str)
|
||||
elsif key.to_s.match(/^(.*)_b$/)
|
||||
result << str.bbcode_to_html
|
||||
else
|
||||
result << h(str)
|
||||
end
|
||||
|
||||
out << "<p>"
|
||||
out << "<b>#{name.to_s.capitalize.gsub(/_s/, '').gsub(/_/, ' ')}</b>: "
|
||||
out << result
|
||||
out << "</p>"
|
||||
end
|
||||
raw out
|
||||
end
|
||||
|
||||
def abslink text, url
|
||||
raw link_to text, url
|
||||
end
|
||||
|
||||
def flag country
|
||||
if country and country.to_s.length > 0
|
||||
image_tag "/images/flags/" + country.downcase + ".gif", :width => 18, :height => 12
|
||||
else
|
||||
image_tag "/images/flags/eu.gif"
|
||||
end
|
||||
end
|
||||
|
||||
def add_comments object
|
||||
@comment = Comment.new :commentable => object
|
||||
@comments = object.comments.ordered.with_userteam
|
||||
return_here
|
||||
render :partial => "comments/index"
|
||||
end
|
||||
|
||||
def bbcode
|
||||
link_to "(BBCode)", article_url(:id => 536)
|
||||
end
|
||||
|
||||
def sortable(column, title = nil)
|
||||
title ||= column.titleize
|
||||
css_class = (column == sort_column) ? "current #{sort_direction}" : nil
|
||||
direction = (column == sort_column && sort_direction == "asc") ? "desc" : "asc"
|
||||
link_to title, {:sort => column, :direction => direction}, {:class => css_class}
|
||||
end
|
||||
|
||||
def link_to_remove_fields(name, f)
|
||||
f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
|
||||
end
|
||||
|
||||
def link_to_add_fields(name, f, association)
|
||||
new_object = f.object.class.reflect_on_association(association).klass.new
|
||||
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
|
||||
render(association.to_s.singularize, :f => builder)
|
||||
end
|
||||
link_to_function(name, ("add_fields(this, '#{association}', '#{escape_javascript(fields)}')"))
|
||||
end
|
||||
end
|
18
app/helpers/gathers_helper.rb
Normal file
18
app/helpers/gathers_helper.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
module GathersHelper
|
||||
def render_gather
|
||||
if @gather.status == Gather::STATE_RUNNING
|
||||
headers["Gather"] = "running"
|
||||
render :partial => "running", :layout => false
|
||||
elsif @gather.status == Gather::STATE_VOTING
|
||||
if @gatherer and @gather.gatherer_votes.first(:conditions => {:user_id => cuser.id})
|
||||
headers["Gather"] = "voted"
|
||||
else
|
||||
headers["Gather"] = "voting"
|
||||
end
|
||||
render :partial => "voting", :layout => false
|
||||
elsif @gather.status == Gather::STATE_PICKING or @gather.status == Gather::STATE_FINISHED
|
||||
headers["Gather"] = "picking"
|
||||
render :partial => "picking", :layout => false
|
||||
end
|
||||
end
|
||||
end
|
11
app/helpers/polls_helper.rb
Normal file
11
app/helpers/polls_helper.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
module PollsHelper
|
||||
def add_option_link(name, form)
|
||||
link_to_function name do |page|
|
||||
option = render :partial => 'option', :locals => { :pf => form, :options => Option.new }
|
||||
page << %{
|
||||
this.counter = typeof this.counter == 'undefined' ? 0 : this.counter + 1;
|
||||
$('options').insert({ bottom: "#{ escape_javascript option }".replace(/\\[\\d+\\]/g, "[" + this.counter + "]") });
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
5
app/helpers/topics_helper.rb
Normal file
5
app/helpers/topics_helper.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
module TopicsHelper
|
||||
def lastpost topic
|
||||
topic_url(topic, :page => topic.last_page, :anchor => "post_#{topic.posts.last.id}")
|
||||
end
|
||||
end
|
21
app/helpers/users_helper.rb
Normal file
21
app/helpers/users_helper.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
module UsersHelper
|
||||
def sort_link text, param
|
||||
key = param
|
||||
key += "_reverse" if params[:sort] == param
|
||||
|
||||
options = {
|
||||
:url => {:params => params.merge({:sort => key, :page => nil})},
|
||||
:with => "`_method=get`",
|
||||
:update => 'usersTable',
|
||||
:before => "Element.show('spinner')",
|
||||
:success => "Element.hide('spinner')",
|
||||
}
|
||||
|
||||
html_options = {
|
||||
:title => "Sort by this field",
|
||||
:href => url_for(:params => params.merge({:sort => key, :page => nil})),
|
||||
}
|
||||
|
||||
# link_to_remote text, options, html_options
|
||||
end
|
||||
end
|
59
app/mailers/notifications.rb
Normal file
59
app/mailers/notifications.rb
Normal file
|
@ -0,0 +1,59 @@
|
|||
class Notifications < ActionMailer::Base
|
||||
default :from => "staff@ensl.org"
|
||||
|
||||
def password user, password
|
||||
@user = user
|
||||
@pass = password
|
||||
mail :to => user.email,
|
||||
:subject => 'ENSL account password'
|
||||
end
|
||||
|
||||
def pm user, pm
|
||||
@user = user
|
||||
@pm = pm
|
||||
mail :to => user.email,
|
||||
:subject => 'New ENSL private message'
|
||||
end
|
||||
|
||||
def gather user, gather
|
||||
@user = user
|
||||
@gather = gather
|
||||
mail :to => user.email,
|
||||
:subject => 'ENSL gather running'
|
||||
end
|
||||
|
||||
def comments user, object
|
||||
@user = user
|
||||
@object = object
|
||||
mail :to => user.email,
|
||||
:subject => 'New ENSL comments'
|
||||
end
|
||||
|
||||
def challenge user, challenge
|
||||
@user = user
|
||||
@challenge = challenge
|
||||
mail :to => user.email,
|
||||
:subject => 'New ENSL challenge'
|
||||
end
|
||||
|
||||
def match user, match
|
||||
@user = user
|
||||
@match = match
|
||||
mail :to => user.email,
|
||||
:subject => 'New ENSL match'
|
||||
end
|
||||
|
||||
def news user, news
|
||||
@user = user
|
||||
@news = news
|
||||
mail :to => user.email,
|
||||
:subject => 'News on ENSL: ' + news.title
|
||||
end
|
||||
|
||||
def article user, article
|
||||
@user = user
|
||||
@article = article
|
||||
mail :to => user.email,
|
||||
:subject => 'News on ENSL: ' + article.title
|
||||
end
|
||||
end
|
130
app/models/article.rb
Normal file
130
app/models/article.rb
Normal file
|
@ -0,0 +1,130 @@
|
|||
require File.join(Rails.root, 'vendor', 'plugins', 'has_view_count', 'init.rb')
|
||||
require 'rbbcode'
|
||||
|
||||
class Article < ActiveRecord::Base
|
||||
include Exceptions
|
||||
include Extra
|
||||
|
||||
STATUS_PUBLISHED = 0
|
||||
STATUS_DRAFT = 1
|
||||
|
||||
RULES = 400
|
||||
HISTORY = 401
|
||||
HOF = 402
|
||||
SPONSORS = 403
|
||||
LINKS = 404
|
||||
COMPETITIVE = 405
|
||||
PLUGIN = 426
|
||||
EXTRA = 428
|
||||
SB_RULES = 450
|
||||
G_RULES = 464
|
||||
|
||||
attr_protected :id, :updated_at, :created_at, :user_id, :version
|
||||
|
||||
scope :recent, :order => "created_at DESC", :limit => 8
|
||||
scope :with_comments,
|
||||
:select => "articles.*, COUNT(C.id) AS comment_num",
|
||||
:joins => "LEFT JOIN comments C ON C.commentable_type = 'Article' AND C.commentable_id = articles.id",
|
||||
:group => "articles.id"
|
||||
scope :ordered, :order => "articles.created_at DESC"
|
||||
scope :limited, :limit => 5
|
||||
scope :nodrafts, :conditions => {:status => STATUS_PUBLISHED}
|
||||
scope :drafts, :conditions => {:status => STATUS_DRAFT}
|
||||
scope :articles, :conditions => ["category_id IN (SELECT id FROM categories WHERE domain = ?)", Category::DOMAIN_ARTICLES]
|
||||
scope :onlynews, :conditions => ["category_id IN (SELECT id FROM categories WHERE domain = ?)", Category::DOMAIN_NEWS]
|
||||
scope :category, lambda { |cat| {:conditions => {:category_id => cat}} }
|
||||
scope :domain, lambda { |domain| {:include => "category", :conditions => {"categories.domain" => domain}} }
|
||||
scope :nospecial, :conditions => ["category_id != ?", Category::SPECIAL]
|
||||
scope :interviews, :conditions => ["category_id = ?", Category::INTERVIEWS]
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :category
|
||||
has_many :comments, :as => :commentable, :order => "created_at ASC", :dependent => :destroy
|
||||
has_many :files, :class_name => "DataFile", :order => "created_at DESC", :dependent => :destroy
|
||||
|
||||
validates_length_of :title, :in => 1..50
|
||||
validates_length_of :text, :in => 1..64000
|
||||
validates_presence_of :user, :category
|
||||
validate :validate_status
|
||||
|
||||
before_validation :init_variables, :if => Proc.new{ |model| model.new_record? }
|
||||
before_save :format_text
|
||||
after_save :send_notifications
|
||||
after_destroy :remove_readings
|
||||
|
||||
has_view_count
|
||||
acts_as_readable
|
||||
acts_as_versioned
|
||||
|
||||
non_versioned_columns << 'category_id'
|
||||
non_versioned_columns << 'status'
|
||||
non_versioned_columns << 'user_id'
|
||||
|
||||
def to_s
|
||||
title
|
||||
end
|
||||
|
||||
def previous_article
|
||||
category.articles.nodrafts.first(:conditions => ["id < ?", self.id], :order => "id DESC")
|
||||
end
|
||||
|
||||
def next_article
|
||||
category.articles.nodrafts.first(:conditions => ["id > ?", self.id], :order => "id ASC")
|
||||
end
|
||||
|
||||
def statuses
|
||||
{STATUS_PUBLISHED => "Published", STATUS_DRAFT => "Draft"}
|
||||
end
|
||||
|
||||
def validate_status
|
||||
errors.add :status, I18n.t(:invalid_status) unless statuses.include? status
|
||||
end
|
||||
|
||||
def init_variables
|
||||
self.status = STATUS_DRAFT unless user.admin?
|
||||
self.text_coding = CODING_BBCODE if !user.admin? and text_coding = CODING_HTML
|
||||
end
|
||||
|
||||
def format_text
|
||||
if text_coding == CODING_BBCODE
|
||||
self.text_parsed = RbbCode::Parser.new.parse(text)
|
||||
elsif text_coding == CODING_MARKDOWN
|
||||
self.text_parsed = BlueCloth.new(text).to_html
|
||||
end
|
||||
end
|
||||
|
||||
def send_notifications
|
||||
if (new_record? or status_changed?) and status == STATUS_PUBLISHED
|
||||
case category.domain
|
||||
when Category::DOMAIN_NEWS
|
||||
Profile.all(:include => :user, :conditions => "notify_news = 1").each do |p|
|
||||
Notifications.news p.user, self if p.user
|
||||
end
|
||||
when Category::DOMAIN_ARTICLES
|
||||
Profile.all(:include => :user, :conditions => "notify_articles = 1").each do |p|
|
||||
Notifications.article p.user, self if p.user
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def remove_readings
|
||||
Reading.delete_all ["readable_type = 'Category' AND readable_id = ?", category_id]
|
||||
end
|
||||
|
||||
def can_show? cuser
|
||||
status != STATUS_DRAFT or (cuser and (user == cuser or cuser.admin?))
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
cuser and !cuser.banned?(Ban::TYPE_MUTE)
|
||||
end
|
||||
|
||||
def can_update? cuser, params = {}
|
||||
cuser and !cuser.banned?(Ban::TYPE_MUTE) and (cuser.admin? or (user == cuser and !params.keys.include? "status"))
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
end
|
88
app/models/ban.rb
Normal file
88
app/models/ban.rb
Normal file
|
@ -0,0 +1,88 @@
|
|||
class Ban < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
TYPE_SITE = 0
|
||||
TYPE_MUTE = 1
|
||||
TYPE_LEAGUE = 2
|
||||
TYPE_SERVER = 3
|
||||
TYPE_VENT = 4
|
||||
TYPE_GATHER = 5
|
||||
VENT_BANS = "tmp/bans.txt"
|
||||
|
||||
attr_protected :id, :created_at, :updated_at
|
||||
attr_accessor :ts, :sign, :len, :user_name
|
||||
|
||||
scope :ordered, :order => "created_at DESC"
|
||||
scope :effective, :conditions => "expiry > UTC_TIMESTAMP()"
|
||||
scope :ineffective, :conditions => "expiry < UTC_TIMESTAMP()"
|
||||
|
||||
validate :validate_ts
|
||||
validate :validate_type
|
||||
validate :validate_ventban
|
||||
validates_format_of :steamid, :with => /\A([0-9]{1,10}:){2}[0-9]{1,10}\Z/, :allow_blank => true
|
||||
validates_format_of :addr, :with => /\A([0-9]{1,3}\.){3}[0-9]{1,3}:?[0-9]{0,5}\z/, :allow_blank => true
|
||||
validates_length_of :reason, :maximum => 255, :allow_nil => true, :allow_blank => true
|
||||
|
||||
before_validation :check_user
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :server
|
||||
|
||||
def color
|
||||
expiry.past? ? "green" : "red"
|
||||
end
|
||||
|
||||
def types
|
||||
{TYPE_SITE => "Website Logon",
|
||||
TYPE_MUTE => "Commenting",
|
||||
TYPE_LEAGUE => "Contests",
|
||||
TYPE_SERVER => "NS Servers",
|
||||
TYPE_VENT => "Ventrilo",
|
||||
TYPE_GATHER => "Gather"}
|
||||
end
|
||||
|
||||
def validate_ts
|
||||
if ts and Verification.verify(steamid + ts.to_s) != sign
|
||||
errors.add :ts, I18n.t(:wrong_verification_code)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_type
|
||||
errors.add :ban_type, I18n.t(:invalid_ban_type) unless types.include? ban_type
|
||||
end
|
||||
|
||||
def validate_ventban
|
||||
if ban_type == TYPE_VENT and !ip.match(/\A([0-9]{1,3}\.){3}[0-9]{1,3}\z/)
|
||||
errors.add :ip, I18n.t(:ventrilos_ip_ban)
|
||||
end
|
||||
end
|
||||
|
||||
def check_user
|
||||
if user_name
|
||||
self.user = User.find_by_username(user_name)
|
||||
else
|
||||
self.user = User.first(:conditions => {:steamid => steamid})
|
||||
self.server = Server.first(:conditions => ["CONCAT(ip, ':', port) = ?", addr])
|
||||
end
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def self.refresh
|
||||
#file = File.new(VENT_BANS, "w")
|
||||
#Ban.all(:conditions => ["ban_type = ? AND expiry > UTC_TIMESTAMP()", TYPE_VENT]).each do |ban|
|
||||
# file.write "#{ban.ip},,,"
|
||||
#end
|
||||
#file.close
|
||||
end
|
||||
end
|
69
app/models/bracket.rb
Normal file
69
app/models/bracket.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
class Bracket < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
attr_protected :id, :created_at, :updated_at
|
||||
|
||||
belongs_to :contest
|
||||
has_many :bracketers
|
||||
|
||||
def to_s
|
||||
"#" + self.id.to_s
|
||||
end
|
||||
|
||||
def get_bracketer row, col
|
||||
b = bracketers.pos(row, col).first
|
||||
unless b
|
||||
b = bracketers.build
|
||||
b.row = row.to_i
|
||||
b.column = col.to_i
|
||||
b.save
|
||||
end
|
||||
return b
|
||||
end
|
||||
|
||||
def options
|
||||
["-- Matches"] \
|
||||
+ contest.matches.collect{|c| [c, "match_#{c.id}"]} \
|
||||
+ ["-- Teams"] \
|
||||
+ contest.contesters.collect{|c| [c, "contester_#{c.id}"]}
|
||||
end
|
||||
|
||||
def default row, col
|
||||
if b = bracketers.pos(row, col).first
|
||||
if b.match
|
||||
return "match_#{b.match_id}"
|
||||
elsif b.contester
|
||||
return "contester_#{b.team_id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_cells params
|
||||
params.each do |row, cols|
|
||||
cols.each do |col, val|
|
||||
unless val.include? "--"
|
||||
b = get_bracketer(row, col)
|
||||
if m = val.match(/match_(\d*)/)
|
||||
b.update_attribute :match_id, m[1].to_i
|
||||
b.update_attribute :team_id, nil
|
||||
elsif m = val.match(/contester_(\d*)/)
|
||||
b.update_attribute :team_id, m[1].to_i
|
||||
b.update_attribute :match_id, nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
end
|
25
app/models/bracketer.rb
Normal file
25
app/models/bracketer.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
class Bracketer < ActiveRecord::Base
|
||||
include Exceptions
|
||||
include Extra
|
||||
|
||||
attr_protected :id, :updated_at, :created_at
|
||||
|
||||
belongs_to :contest
|
||||
belongs_to :match
|
||||
belongs_to :contester, :foreign_key => "team_id"
|
||||
|
||||
scope :pos, lambda { |row, col| {:conditions => {"row" => row, "column" => col}} }
|
||||
|
||||
def to_s
|
||||
if self.match_id
|
||||
if match.match_time.past? and (match.score1 and match.score2)
|
||||
winner = match.score1 > match.score2 ? match.contester1.team : match.contester2.team
|
||||
return "#{self.match.score1} - #{self.match.score2}"
|
||||
else
|
||||
return self.match.match_time.strftime("%H:%M %d/%b")
|
||||
end
|
||||
elsif self.contester
|
||||
return self.contester.to_s[0, 10]
|
||||
end
|
||||
end
|
||||
end
|
70
app/models/category.rb
Normal file
70
app/models/category.rb
Normal file
|
@ -0,0 +1,70 @@
|
|||
class Category < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
MAIN = 1
|
||||
SPECIAL = 10
|
||||
INTERVIEWS = 11
|
||||
RULES = 36
|
||||
|
||||
DOMAIN_NEWS = 0
|
||||
DOMAIN_ARTICLES = 1
|
||||
DOMAIN_ISSUES = 2
|
||||
DOMAIN_SITES = 3
|
||||
DOMAIN_FORUMS = 4
|
||||
DOMAIN_MOVIES = 5
|
||||
DOMAIN_GAMES = 6
|
||||
|
||||
PER_PAGE = 3
|
||||
|
||||
attr_protected :id, :updated_at, :created_at, :sort
|
||||
|
||||
validates_length_of :name, :in => 1..30
|
||||
validate :validate_domain
|
||||
|
||||
scope :ordered, :order => "sort ASC, created_at DESC"
|
||||
scope :domain, lambda { |domain| {:conditions => {:domain => domain}} }
|
||||
scope :nospecial, :conditions => ["name != 'Special'"]
|
||||
scope :newest, :include => :articles, :order => "articles.created_at DESC"
|
||||
scope :page, lambda { |page| {:limit => "#{(page-1)*PER_PAGE}, #{(page-1)*PER_PAGE+PER_PAGE}"} }
|
||||
scope :of_user, lambda { |user| {:conditions => {"articles.user_id" => user.id}, :include => :articles} }
|
||||
|
||||
has_many :articles, :order => "created_at DESC"
|
||||
has_many :issues, :order => "created_at DESC"
|
||||
has_many :forums, :order => "forums.position"
|
||||
has_many :movies
|
||||
has_many :maps
|
||||
has_many :gathers
|
||||
has_many :servers
|
||||
|
||||
acts_as_readable
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
def domains
|
||||
{DOMAIN_NEWS => 'News',
|
||||
DOMAIN_ARTICLES => 'Articles',
|
||||
DOMAIN_ISSUES => 'Issues',
|
||||
DOMAIN_SITES => "Sites",
|
||||
DOMAIN_FORUMS => "Forums",
|
||||
DOMAIN_MOVIES => "Movies",
|
||||
DOMAIN_GAMES => "Games"}
|
||||
end
|
||||
|
||||
def validate_domain
|
||||
errors.add :domain, I18n.t(:invalid_domain) unless domains.include? domain
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
end
|
239
app/models/challenge.rb
Normal file
239
app/models/challenge.rb
Normal file
|
@ -0,0 +1,239 @@
|
|||
class Challenge < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
STATUS_PENDING = 0
|
||||
STATUS_ACCEPTED = 1
|
||||
STATUS_DEFAULT = 2
|
||||
STATUS_FORFEIT = 3
|
||||
STATUS_DECLINED = 4
|
||||
AUTO_DEFAULT_TIME = 10800 # Normal default time: 3 hours
|
||||
CHALLENGE_BEFORE_MANDATORY = 432000 # Min. time threshold for mandatory matches: 5 days
|
||||
CHALLENGE_BEFORE_VOLUNTARY = 900 # Min. time threshold for voluntary matches: 15 mins
|
||||
ACCEPT_BEFORE_MANDATORY = 86400 # Time to accept before mandatory match time: 1 day
|
||||
ACCEPT_BEFORE_VOLUNTARY = 300 # Time to accept before voluntary match time: 5 mins
|
||||
MATCH_LENGTH = 7200 # Usual match length (for servers): 2 hours
|
||||
|
||||
attr_protected :id, :updated_at, :created_at, :default_time, :user_id, :status
|
||||
|
||||
validates_presence_of :contester1, :contester2, :server, :map1
|
||||
validates_presence_of :map2, :on => :update
|
||||
#validates_datetime :match_time, :default_time
|
||||
#validates_length_of [:details, :response], :maximum => 255, :allow_blank => true, :allow_nil => true
|
||||
#validate_on_create:validate_teams
|
||||
#validate_on_create:validate_contest
|
||||
#validate_on_create:validate_mandatory
|
||||
#validate_on_create:validate_match_time
|
||||
#validate_on_create:validate_server
|
||||
#validate_on_create:validate_map1
|
||||
#validate_on_update :validate_map2
|
||||
#validate_on_update :validate_status
|
||||
|
||||
scope :of_contester,
|
||||
lambda { |contester| {:conditions => ["contester1_id = ? OR contester2_id = ?", contester.id, contester.id]} }
|
||||
scope :within_time,
|
||||
lambda { |from, to| {:conditions => ["match_time > ? AND match_time < ?", from.utc, to.utc]} }
|
||||
scope :around,
|
||||
lambda { |time| {:conditions => ["match_time > ? AND match_time < ?", time.ago(MATCH_LENGTH).utc, time.ago(-MATCH_LENGTH).utc]} }
|
||||
scope :on_week,
|
||||
lambda { |time| {:conditions => ["match_time > ? and match_time < ?", time.beginning_of_week, time.end_of_week]} }
|
||||
scope :pending, :conditions => {:status => STATUS_PENDING}
|
||||
scope :mandatory, :conditions => {:mandatory => true}
|
||||
scope :future, :conditions => "match_time > UTC_TIMESTAMP()"
|
||||
scope :past, :conditions => "match_time < UTC_TIMESTAMP()"
|
||||
|
||||
has_one :match
|
||||
belongs_to :map1, :class_name => "Map"
|
||||
belongs_to :map2, :class_name => "Map"
|
||||
belongs_to :user
|
||||
belongs_to :server
|
||||
belongs_to :contester1, :class_name => "Contester", :include => 'team'
|
||||
belongs_to :contester2, :class_name => "Contester", :include => 'team'
|
||||
|
||||
def statuses
|
||||
{STATUS_PENDING => "Pending response",
|
||||
STATUS_ACCEPTED => "Accepted",
|
||||
STATUS_DEFAULT => "Default Time",
|
||||
STATUS_FORFEIT => "Forfeited",
|
||||
STATUS_DECLINED => "Declined"}
|
||||
end
|
||||
|
||||
def autodefault
|
||||
match_time - (mandatory ? ACCEPT_BEFORE_MANDATORY : ACCEPT_BEFORE_VOLUNTARY)
|
||||
end
|
||||
|
||||
def get_margin
|
||||
mandatory ? CHALLENGE_BEFORE_MANDATORY : CHALLENGE_BEFORE_VOLUNTARY
|
||||
end
|
||||
|
||||
def get_deadline
|
||||
mandatory ? ACCEPT_BEFORE_MANDATORY : ACCEPT_BEFORE_VOLUNTARY
|
||||
end
|
||||
|
||||
def get_contester1
|
||||
self.contester1 = user.active_contesters.of_contest(contester2.contest).first
|
||||
end
|
||||
|
||||
def before_validation_on_create
|
||||
self.status = STATUS_PENDING
|
||||
self.default_time = match_time.end_of_week.change \
|
||||
:hour => contester1.contest.default_time.hour,
|
||||
:minute => contester1.contest.default_time.strftime("%M").to_i
|
||||
end
|
||||
|
||||
def after_create
|
||||
contester2.team.teamers.active.leaders.each do |teamer|
|
||||
if teamer.user.profile.notify_pms
|
||||
Notifications.challenge teamer.user, self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def validate_teams
|
||||
if contester1.team == contester2.team
|
||||
errors.add_to_base I18n.t(:challenges_yourself)
|
||||
end
|
||||
if contester1.contest != contester2.contest
|
||||
errors.add_to_base I18n.t(:challenges_opponent_contest)
|
||||
end
|
||||
if !contester2.active or !contester2.team.active
|
||||
errors.add_to_base I18n.t(:challenges_opponent_inactive)
|
||||
end
|
||||
if !contester1.active or !contester1.team.active
|
||||
errors.add_to_base I18n.t(:challenges_inactive)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_contest
|
||||
if contester1.contest.end.past? or contester1.contest.status == Contest::STATUS_CLOSED
|
||||
errors.add_to_base I18n.t(:contests_closed)
|
||||
end
|
||||
if contester1.contest.contest_type != Contest::TYPE_LADDER and !match
|
||||
errors.add_to_base I18n.t(:contests_notladder)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_mandatory
|
||||
return unless mandatory
|
||||
|
||||
if contester2.score < contester1.score
|
||||
errors.add_to_base I18n.t(:challenges_mandatory)
|
||||
end
|
||||
if Challenge.pending.count(:conditions => \
|
||||
["contester1_id = ? AND contester2_id = ? AND mandatory = true AND default_time < UTC_TIMESTAMP()",
|
||||
contester1.id, contester2.id]) > 0
|
||||
errors.add_to_base I18n.t(:challenges_mandatory_handled)
|
||||
end
|
||||
if Match.of_contester(contester2).on_week(match_time).count > 0
|
||||
errors.add_to_base I18n.t(:challenges_opponent_week)
|
||||
end
|
||||
if Challenge.of_contester(contester2).mandatory.on_week(match_time).count > 0
|
||||
errors.add_to_base I18n.t(:challenges_opponent_mandatory_week)
|
||||
end
|
||||
if Challenge.of_contester(contester2).mandatory.on_week(default_time).count > 0
|
||||
errors.add_to_base I18n.t(:challenges_opponent_mandatory_week_defaulttime)
|
||||
end
|
||||
if Match.of_contester(contester2).around(default_time).count > 0
|
||||
errors.add_to_base I18n.t(:challenges_opponent_defaulttime)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_match_time
|
||||
if (match_time-get_margin).past?
|
||||
if get_margin > 86400
|
||||
errors.add_to_base I18n.t(:matches_time1) + get_margin / 60 / 60 / 24 + I18n.t(:matches_time2)
|
||||
else
|
||||
errors.add_to_base I18n.t(:matches_time1) + get_margin / 60 + I18n.t(:matches_time3)
|
||||
end
|
||||
end
|
||||
if Challenge.of_contester(contester2).around(match_time).pending.count > 0
|
||||
errors.add_to_base I18n.t(:challenges_opponent_specifictime)
|
||||
end
|
||||
if Match.of_contester(contester2).around(match_time).count > 0
|
||||
errors.add_to_base I18n.t(:challenges_opponent_match_specifictime)
|
||||
end
|
||||
if match_time > contester1.contest.end
|
||||
errors.add_to_base I18n.t(:contests_end)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_server
|
||||
unless server and server.official
|
||||
errors.add_to_base I18n.t(:servers_notavailable)
|
||||
end
|
||||
unless server.is_free match_time
|
||||
errors.add_to_base I18n.t(:servers_notfree_specifictime)
|
||||
end
|
||||
if !server.is_free default_time
|
||||
errors.add_to_base I18n.t(:servers_notfree_defaulttime)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_map1
|
||||
unless contester1.contest.maps.exists?(map1)
|
||||
errors.add_to_base I18n.t(:contests_map_notavailable)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_map2
|
||||
unless contester2.contest.maps.exists?(map2)
|
||||
errors.add_to_base I18n.t(:contests_map_notavailable)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_status
|
||||
if mandatory and ![STATUS_ACCEPTED, STATUS_DEFAULT, STATUS_FORFEIT].include? status
|
||||
errors.add_to_base I18n.t(:challenges_mandatory_invalidresult)
|
||||
end
|
||||
unless statuses.include? status
|
||||
errors.add_to_base I18n.t(:challenges_mandatory_invalidresult)
|
||||
end
|
||||
end
|
||||
|
||||
def after_update
|
||||
if status_changed?
|
||||
if status == STATUS_ACCEPTED
|
||||
make_match.save
|
||||
elsif status == STATUS_DEFAULT
|
||||
m = make_match
|
||||
m.match_time = default_time
|
||||
m.save
|
||||
elsif status == STATUS_FORFEIT
|
||||
m = make_match
|
||||
m.forfeit = true
|
||||
m.score1 = 4
|
||||
m.score2 = 0
|
||||
m.match_time = default_time
|
||||
m.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_match
|
||||
match = Match.new
|
||||
match.contester1 = contester1
|
||||
match.contester2 = contester2
|
||||
match.map1 = map1
|
||||
match.map2 = map2
|
||||
match.contest = contester1.contest
|
||||
match.challenge = self
|
||||
match.server = server
|
||||
match.match_time = match_time
|
||||
match
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
return false unless cuser
|
||||
return false if cuser.banned?(Ban::TYPE_LEAGUE)
|
||||
validate_teams
|
||||
validate_contest
|
||||
true if (contester1.team.is_leader?(cuser) or cuser.admin?) and errors.size == 0
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and (contester2.team.is_leader? cuser or cuser.admin?) and status == STATUS_PENDING and autodefault.future?
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and (contester1.team.is_leader? cuser or cuser.admin?) and status == STATUS_PENDING and autodefault.future?
|
||||
end
|
||||
end
|
50
app/models/comment.rb
Normal file
50
app/models/comment.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
require 'rbbcode'
|
||||
|
||||
class Comment < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
attr_protected :id, :updated_at, :created_at, :user_id
|
||||
|
||||
scope :with_userteam, :include => {:user => :team}
|
||||
scope :recent, :order => "id DESC", :limit => 10
|
||||
scope :recent3, :order => "id DESC", :limit => 3
|
||||
scope :recent5, :order => "id DESC", :limit => 5, :group => "commentable_id, commentable_type"
|
||||
scope :filtered, :conditions => ["commentable_type != 'Issue'"]
|
||||
scope :ordered, :order => "id ASC"
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :commentable, :polymorphic => true
|
||||
|
||||
validates_presence_of :commentable, :user
|
||||
validates_length_of :text, :in => 1..10000
|
||||
|
||||
before_save :parse_text
|
||||
|
||||
# acts_as_indexed :fields => [:text]
|
||||
|
||||
def parse_text
|
||||
self.text_parsed = RbbCode::Parser.new.parse(text)
|
||||
end
|
||||
|
||||
def after_create
|
||||
# if commentable_type == "Movie" or commentable_type == "Article" and commentable.user and commentable.user.profile.notify_own_stuff
|
||||
# Notifications.deliver_comments commentable.user, commentable
|
||||
# end
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
return false unless cuser
|
||||
#errors.add_to_base I18n.t(:comments_locked) if !commentable.lock.nil? and commentable.lock
|
||||
errors.add_to_base I18n.t(:bans_mute) if cuser.banned? Ban::TYPE_MUTE
|
||||
errors.add_to_base I18n.t(:registered_for_week) unless cuser.verified?
|
||||
return errors.count == 0
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and user == cuser or cuser.admin?
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
end
|
114
app/models/contest.rb
Normal file
114
app/models/contest.rb
Normal file
|
@ -0,0 +1,114 @@
|
|||
class Contest < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
WEIGHT = 30.0
|
||||
STATUS_OPEN = 0
|
||||
STATUS_PROGRESS = 1
|
||||
STATUS_CLOSED = 3
|
||||
TYPE_LADDER = 0
|
||||
TYPE_LEAGUE = 1
|
||||
TYPE_BRACKET = 2
|
||||
|
||||
attr_protected :id, :updated_at, :created_at
|
||||
|
||||
scope :active, :conditions => ["status != ?", STATUS_CLOSED]
|
||||
scope :inactive, :conditions => {:status => STATUS_CLOSED}
|
||||
scope :joinable, :conditions => {:status => STATUS_OPEN}
|
||||
scope :with_contesters, :include => :contesters
|
||||
scope :ordered, :order => "start DESC"
|
||||
scope :nsls1, :conditions => ["name LIKE ?", "NSL S1:%"]
|
||||
scope :nsls2, :conditions => ["name LIKE ?", "NSL S2:%"]
|
||||
scope :ns1seasons, :conditions => ["name LIKE ?", "S%:%"]
|
||||
|
||||
has_many :matches, :dependent => :destroy
|
||||
has_many :weeks, :dependent => :destroy
|
||||
has_many :contesters, :dependent => :destroy, :include => :team
|
||||
has_many :predictions, :through => :matches
|
||||
has_many :brackets
|
||||
has_many :preds_with_score,
|
||||
:source => :predictions,
|
||||
:through => :matches,
|
||||
:select => "predictions.id, predictions.user_id,
|
||||
SUM(result) AS correct,
|
||||
SUM(result)/COUNT(*)*100 AS score,
|
||||
COUNT(*) AS total",
|
||||
:conditions => "result IS NOT NULL",
|
||||
:group => "predictions.user_id",
|
||||
:order => "correct DESC"
|
||||
has_and_belongs_to_many :maps
|
||||
belongs_to :demos, :class_name => "Directory"
|
||||
belongs_to :winner, :class_name => "Contester"
|
||||
belongs_to :rules, :class_name => "Article"
|
||||
|
||||
validates_presence_of :name, :start, :end, :status, :default_time
|
||||
validates_length_of :name, :in => 1..50
|
||||
validates_length_of :short_name, :in => 1..8, :allow_nil => true
|
||||
validate :validate_status
|
||||
validate :validate_contest_type
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
def status_s
|
||||
statuses[status]
|
||||
end
|
||||
|
||||
def default_s
|
||||
"Sunday " + default_time.to_s
|
||||
end
|
||||
|
||||
def statuses
|
||||
{STATUS_OPEN => "In Progress (signups open)", STATUS_PROGRESS => "In Progress (signups closed)", STATUS_CLOSED => "Closed"}
|
||||
end
|
||||
|
||||
def types
|
||||
{TYPE_LADDER => "Ladder", TYPE_LEAGUE => "League", TYPE_BRACKET => "Bracket"}
|
||||
end
|
||||
|
||||
def validate_status
|
||||
errors.add :status, I18n.t(:invalid_status) unless statuses.include? status
|
||||
end
|
||||
|
||||
def validate_contest_type
|
||||
errors.add :contest_type, I18n.t(:contests_invalidtype) unless types.include? contest_type
|
||||
end
|
||||
|
||||
def recalculate
|
||||
Match.update_all("diff = null, points1 = null, points2 = null", {:contest_id => self.id})
|
||||
Contester.update_all("score = 0, win = 0, loss = 0, draw = 0, extra = 0", {:contest_id => self.id})
|
||||
matches.finished.chrono.each do |match|
|
||||
match.recalculate
|
||||
match.save
|
||||
end
|
||||
end
|
||||
|
||||
def elo_score score1, score2, diff, level = self.modulus_base, weight = self.weight, moduluses = [self.modulus_even, self.modulus_3to1, self.modulus_4to0]
|
||||
points = (score2-score1).abs
|
||||
modulus = moduluses[0].to_f if points <= 1
|
||||
modulus = moduluses[1].to_f if points == 2
|
||||
modulus = moduluses[2].to_f if points >= 3
|
||||
if score1 == score2
|
||||
result = 0.5
|
||||
elsif score1 > score2
|
||||
result = 1.0
|
||||
elsif score2 > score1
|
||||
result = 0.0
|
||||
end
|
||||
prob = 1.0/(10**(diff.to_f/weight.to_f)+1.0)
|
||||
total = (level.to_f*modulus*(result-prob)).round
|
||||
return total
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
end
|
100
app/models/contester.rb
Normal file
100
app/models/contester.rb
Normal file
|
@ -0,0 +1,100 @@
|
|||
class Contester < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
TREND_FLAT = 0
|
||||
TREND_UP = 1
|
||||
TREND_DOWN = 2
|
||||
|
||||
attr_protected :id, :updated_at, :created_at, :trend
|
||||
attr_accessor :user
|
||||
|
||||
scope :active, :include => :team, :conditions => {"contesters.active" => true}
|
||||
scope :ordered, :select => "contesters.*, (score + extra) AS total_score", :order => "total_score DESC, score DESC, win DESC, loss ASC"
|
||||
scope :chronological, :order => "created_at DESC"
|
||||
scope :of_contest, lambda { |contest| {:conditions => {"contesters.contest_id" => contest.id}} }
|
||||
|
||||
has_many :challenges_sent, :class_name => "Challenge", :foreign_key => "contester1_id"
|
||||
has_many :challenges_received, :class_name => "Challenge", :foreign_key => "contester2_id"
|
||||
has_many :matches, :through => :contest, :conditions => "(contester1_id = contesters.id OR contester2_id = contesters.id)"
|
||||
belongs_to :team
|
||||
belongs_to :contest
|
||||
|
||||
validates_presence_of :team, :contest
|
||||
validates_inclusion_of [:score, :win, :loss, :draw, :extra], :in => 0..9999, :allow_nil => true
|
||||
validates_uniqueness_of :team_id, :scope => :contest_id, :message => "You can't join same contest twice."
|
||||
#validate_on_create:validate_member_participation
|
||||
#validate_on_create:validate_contest
|
||||
#validate_on_create:validate_playernumber
|
||||
|
||||
before_create :init_variables
|
||||
|
||||
|
||||
def to_s
|
||||
team.to_s
|
||||
end
|
||||
|
||||
def total
|
||||
score + extra.to_i
|
||||
end
|
||||
|
||||
def statuses
|
||||
{false => "Inactive", true => "Active"}
|
||||
end
|
||||
|
||||
def lineup
|
||||
contest.status == Contest::STATUS_CLOSED ? team.teamers.distinct : team.teamers.active
|
||||
end
|
||||
|
||||
def get_matches
|
||||
contest.matches.all :conditions => ["contester1_id = ? OR contester2_id = ?", id, id]
|
||||
end
|
||||
|
||||
def init_variables
|
||||
self.active = true
|
||||
self.trend = Contester::TREND_FLAT
|
||||
self.extra = 0
|
||||
end
|
||||
|
||||
def validate_member_participation
|
||||
# TODO joku erhe
|
||||
# for member in team.teamers.present do
|
||||
# for team in member.user.active_teams do
|
||||
# if team.contesters.active.exists?(:contest_id => contest_id)
|
||||
# errors.add_to_base "Member #{member.user} is already participating with team #{team.name}"
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
def validate_contest
|
||||
if contest.end.past? or contest.status == Contest::STATUS_CLOSED
|
||||
errors.add :contest, I18n.t(:contests_closed)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_playernumber
|
||||
if team.teamers.active.distinct.count < 6
|
||||
errors.add :team, I18n.t(:contests_join_need6)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
update_attribute :active, false
|
||||
end
|
||||
|
||||
def can_create? cuser, params = {}
|
||||
return false unless cuser
|
||||
return false if cuser.banned?(Ban::TYPE_LEAGUE)
|
||||
return true if cuser.admin?
|
||||
return true if team.is_leader? cuser and Verification.contain params, [:team_id, :contest_id]
|
||||
return false
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and team.is_leader? cuser or cuser.admin?
|
||||
end
|
||||
end
|
137
app/models/data_file.rb
Normal file
137
app/models/data_file.rb
Normal file
|
@ -0,0 +1,137 @@
|
|||
require File.join(Rails.root, 'vendor', 'plugins', 'acts_as_rateable', 'init.rb')
|
||||
require 'digest/md5'
|
||||
|
||||
class DataFile < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
MEGABYTE = 1048576
|
||||
|
||||
attr_accessor :related_id
|
||||
attr_protected :id, :updated_at, :created_at, :path, :size, :md5
|
||||
|
||||
scope :recent, :order => "created_at DESC", :limit => 8
|
||||
scope :demos, :order => "created_at DESC", :conditions => ["directory_id IN (SELECT id FROM directories WHERE parent_id = ?)", Directory::DEMOS]
|
||||
scope :ordered, :order => "created_at DESC"
|
||||
scope :movies, :order => "created_at DESC", :conditions => {:directory_id => Directory::MOVIES}
|
||||
scope :not, lambda { |file| {:conditions => ["id != ?", file.id]} }
|
||||
scope :unrelated, :conditions => "related_id is null"
|
||||
|
||||
has_many :related_files, :class_name => "DataFile", :foreign_key => :related_id
|
||||
has_many :comments, :as => :commentable
|
||||
has_one :movie, :foreign_key => :file_id, :dependent => :destroy
|
||||
has_one :preview, :class_name => "Movie", :foreign_key => :preview_id, :dependent => :nullify
|
||||
has_one :match, :foreign_key => :demo_id
|
||||
belongs_to :directory
|
||||
belongs_to :related, :class_name => "DataFile"
|
||||
belongs_to :article
|
||||
|
||||
validates_length_of [:description, :path], :maximum => 255
|
||||
|
||||
before_save :process_file
|
||||
after_create :create_movie, :if => Proc.new {|file| file.directory_id == Directory::MOVIES and !file.location.include?("_preview.mp4") }
|
||||
after_save :update_relations, :if => Proc.new { |file| file.related_id_changed? and related_files.count > 0 }
|
||||
|
||||
acts_as_rateable
|
||||
mount_uploader :name, FileUploader
|
||||
|
||||
def to_s
|
||||
(description.nil? or description.empty?) ? File.basename(name.to_s) : description
|
||||
end
|
||||
|
||||
def md5_s
|
||||
md5.upcase
|
||||
end
|
||||
|
||||
def extra_url
|
||||
url.to_s.gsub(/^\/files/, "http://extra.ensl.org/static")
|
||||
end
|
||||
|
||||
def size_s
|
||||
(size.to_f/MEGABYTE).round(2).to_s + " MB"
|
||||
end
|
||||
|
||||
def location
|
||||
name.current_path
|
||||
end
|
||||
|
||||
def url
|
||||
name.url
|
||||
end
|
||||
|
||||
def process_file
|
||||
self.md5 = "e948c22100d29623a1df48e1760494df"
|
||||
if article
|
||||
self.directory_id = Directory::ARTICLES
|
||||
end
|
||||
|
||||
if File.exists?(location) and (size != File.size(location) or created_at != File.mtime(location))
|
||||
self.md5 = Digest::MD5.hexdigest(File.read(location))
|
||||
self.size = File.size(location)
|
||||
self.created_at = File.mtime(location)
|
||||
end
|
||||
|
||||
if path.nil? or directory_id_changed?
|
||||
self.path = File.join(directory.path, File.basename(name.to_s))
|
||||
end
|
||||
|
||||
if !new_record? and directory_id_changed? and File.exists?(name.current_path)
|
||||
FileUtils.mv(location, path)
|
||||
end
|
||||
|
||||
if description.nil? or description.empty?
|
||||
self.description = File.basename(location).gsub(/[_\-]/, " ").gsub(/\.\w{1,5}$/, "")
|
||||
self.description = description.split(/\s+/).each{ |word| word.capitalize! }.join(' ')
|
||||
end
|
||||
|
||||
if match
|
||||
self.description = match.contester1.to_s + " vs " + match.contester2.to_s
|
||||
end
|
||||
|
||||
if location.include? "_preview.mp4" and !related
|
||||
stripped = location.gsub(/_preview\.mp4/, "")
|
||||
DataFile.all(:conditions => ["path LIKE ?", stripped + "%"]).each do |r|
|
||||
if r.location.match(/#{stripped}\.\w{1,5}$/)
|
||||
self.related = r
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if movie and (new_record? or md5_changed?)
|
||||
movie.get_length
|
||||
end
|
||||
end
|
||||
|
||||
def create_movie
|
||||
movie = Movie.new
|
||||
movie.file = self
|
||||
movie.make_snapshot 5
|
||||
movie.save
|
||||
end
|
||||
|
||||
def update_relations
|
||||
related_files.each do |rf|
|
||||
rf.related = self.related
|
||||
rf.save
|
||||
end
|
||||
end
|
||||
|
||||
def rateable? user
|
||||
user and !rated_by?(user)
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
return false unless cuser
|
||||
return false if cuser.banned?(Ban::TYPE_MUTE)
|
||||
(cuser.admin? or \
|
||||
(article and article.can_create? cuser) or \
|
||||
(directory_id == Directory::MOVIES and cuser.has_access? Group::MOVIES))
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin? or (article and article.can_create? cuser)
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and cuser.admin? or (article and article.can_create? cuser)
|
||||
end
|
||||
end
|
102
app/models/directory.rb
Normal file
102
app/models/directory.rb
Normal file
|
@ -0,0 +1,102 @@
|
|||
class Directory < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
ROOT = 1
|
||||
DEMOS = 5
|
||||
DEMOS_DEFAULT = 19
|
||||
DEMOS_GATHERS = 92
|
||||
MOVIES = 30
|
||||
ARTICLES = 39
|
||||
|
||||
attr_protected :id, :updated_at, :created_at, :path
|
||||
|
||||
belongs_to :parent, :class_name => "Directory"
|
||||
has_many :subdirs, :class_name => "Directory", :foreign_key => :parent_id
|
||||
has_many :files, :class_name => "DataFile", :order => "name"
|
||||
|
||||
scope :ordered, :order => "name ASC"
|
||||
scope :filtered, :conditions => {:hidden => false}
|
||||
scope :of_parent, lambda { |parent| {:conditions => {:parent_id => parent.id}} }
|
||||
|
||||
validates_length_of [:name, :path], :in => 1..255
|
||||
validates_format_of :name, :with => /\A[A-Za-z0-9]{1,20}\z/, :on => :create
|
||||
validates_length_of :name, :in => 1..25
|
||||
validates_inclusion_of :hidden, :in => [true, false]
|
||||
|
||||
before_validation :init_variables
|
||||
after_create :make_path
|
||||
after_save :update_timestamp
|
||||
before_destroy :remove_files
|
||||
after_destroy :remove_path
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
def init_variables
|
||||
self.path = File.join(parent.path, name.downcase)
|
||||
self.hidden = false if hidden.nil?
|
||||
end
|
||||
|
||||
def make_path
|
||||
Dir.mkdir(path) unless File.exists?(path)
|
||||
end
|
||||
|
||||
def update_timestamp
|
||||
self.created_at = File.mtime(path) if File.exists?(path)
|
||||
end
|
||||
|
||||
def remove_files
|
||||
files.each do |subdir|
|
||||
subdir.destroy
|
||||
end
|
||||
subdirs.each do |subdir|
|
||||
subdir.destroy
|
||||
end
|
||||
end
|
||||
|
||||
def remove_path
|
||||
Dir.unlink(path) if File.exists?(path)
|
||||
end
|
||||
|
||||
def process_dir
|
||||
ActiveRecord::Base.transaction do
|
||||
Dir.glob("#{path}/*").each do |file|
|
||||
if File.directory?(file)
|
||||
if dir = Directory.find_by_path(file)
|
||||
dir.save!
|
||||
else
|
||||
dir = Directory.new
|
||||
dir.name = File.basename(file)
|
||||
dir.path = file
|
||||
dir.parent = self
|
||||
dir.save!
|
||||
end
|
||||
dir.process_dir
|
||||
else
|
||||
if dbfile = DataFile.find_by_path(file)
|
||||
dbfile.directory = self
|
||||
dbfile.save!
|
||||
elsif (File.mtime(file) + 100).past?
|
||||
dbfile = DataFile.new
|
||||
dbfile.path = file
|
||||
dbfile.directory = self
|
||||
dbfile.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_update? cuser, params = {}
|
||||
cuser and cuser.admin? and Verification.contain params, [:description, :hidden]
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
end
|
64
app/models/forum.rb
Normal file
64
app/models/forum.rb
Normal file
|
@ -0,0 +1,64 @@
|
|||
class Forum < ActiveRecord::Base
|
||||
include Extra
|
||||
BANS = 8
|
||||
TRASH = 12
|
||||
|
||||
attr_protected :id, :updated_at, :created_at
|
||||
|
||||
scope :available_to,
|
||||
lambda { |user, level| {
|
||||
:select => "forums.*, groupers.user_id AS access, COUNT(f2.id) AS acl, g2.user_id",
|
||||
:joins => "LEFT JOIN forumers ON forumers.forum_id = forums.id AND forumers.access = #{level}
|
||||
LEFT JOIN forumers AS f2 ON forumers.forum_id = forums.id AND f2.access = #{level}
|
||||
LEFT JOIN groups ON forumers.group_id = groups.id
|
||||
LEFT JOIN groupers ON groupers.group_id = groups.id AND groupers.user_id = #{user.id}
|
||||
LEFT JOIN groupers g2 ON g2.group_id = #{Group::ADMINS} AND g2.user_id = #{user.id}",
|
||||
:group => "forums.id",
|
||||
:having => ["access IS NOT NULL OR acl = 0 OR g2.user_id IS NOT NULL", level]} }
|
||||
scope :public,
|
||||
:select => "forums.*",
|
||||
:joins => "LEFT JOIN forumers ON forumers.forum_id = forums.id AND forumers.access = #{Forumer::ACCESS_READ}",
|
||||
:conditions => "forumers.id IS NULL"
|
||||
scope :of_forum,
|
||||
lambda { |forum| {:conditions => {"forums.id" => forum.id}} }
|
||||
scope :ordered, :order => "position"
|
||||
|
||||
has_many :topics
|
||||
has_many :posts, :through => :topics
|
||||
has_many :forumers
|
||||
has_many :groups, :through => :forumers
|
||||
has_one :forumer
|
||||
belongs_to :category
|
||||
|
||||
after_create :update_position
|
||||
|
||||
acts_as_readable
|
||||
|
||||
def to_s
|
||||
self.title
|
||||
end
|
||||
|
||||
def update_position
|
||||
update_attribute :position, self.id
|
||||
end
|
||||
|
||||
def can_show? cuser
|
||||
if cuser
|
||||
Forum.available_to(cuser, Forumer::ACCESS_READ).of_forum(self).first
|
||||
else
|
||||
Forum.public.of_forum(self).first
|
||||
end
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
end
|
27
app/models/forumer.rb
Normal file
27
app/models/forumer.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
class Forumer < ActiveRecord::Base
|
||||
ACCESS_READ = 0
|
||||
ACCESS_REPLY = 1
|
||||
ACCESS_TOPIC = 2
|
||||
|
||||
include Extra
|
||||
|
||||
scope :access,
|
||||
lambda { |level| {:conditions => ["access >= ?", level]} }
|
||||
|
||||
validates_uniqueness_of :group_id, :scope => [:forum_id, :access]
|
||||
validates_presence_of [:group_id, :forum_id]
|
||||
validates_inclusion_of :access, :in => 0..2
|
||||
|
||||
belongs_to :forum
|
||||
belongs_to :group
|
||||
|
||||
before_create :init_variables
|
||||
|
||||
def init_variables
|
||||
self.access ||= ACCESS_READ
|
||||
end
|
||||
|
||||
def accesses
|
||||
{ACCESS_READ => "Read", ACCESS_REPLY => "Reply", ACCESS_TOPIC => "Post a Topic"}
|
||||
end
|
||||
end
|
176
app/models/gather.rb
Normal file
176
app/models/gather.rb
Normal file
|
@ -0,0 +1,176 @@
|
|||
class Gather < ActiveRecord::Base
|
||||
STATE_RUNNING = 0
|
||||
STATE_VOTING = 3
|
||||
STATE_PICKING = 1
|
||||
STATE_FINISHED = 2
|
||||
NOTIFY = 6
|
||||
FULL = 12
|
||||
SERVERS = [3, 5, 23, 21, 22]
|
||||
|
||||
attr_accessor :admin
|
||||
|
||||
scope :ordered, :order => "id DESC"
|
||||
scope :basic, :include => [:captain1, :captain2, :map1, :map2, :server]
|
||||
scope :active,
|
||||
:conditions => ["gathers.status IN (?, ?, ?) AND gathers.updated_at > ?",
|
||||
STATE_VOTING, STATE_PICKING, STATE_RUNNING, 12.hours.ago.utc]
|
||||
|
||||
belongs_to :server
|
||||
belongs_to :captain1, :class_name => "Gatherer"
|
||||
belongs_to :captain2, :class_name => "Gatherer"
|
||||
belongs_to :map1, :class_name => "GatherMap"
|
||||
belongs_to :map2, :class_name => "GatherMap"
|
||||
belongs_to :category
|
||||
|
||||
has_many :gatherers
|
||||
has_many :users, :through => :gatherers
|
||||
has_many :gatherer_votes, :through => :gatherers, :source => :real_votes
|
||||
has_many :map_votes, :through => :gather_maps, :source => :real_votes
|
||||
has_many :gather_maps, :class_name => "GatherMap"
|
||||
has_many :maps, :through => :gather_maps
|
||||
has_many :server_votes, :through => :gather_servers, :source => :real_votes
|
||||
has_many :gather_servers, :class_name => "GatherServer"
|
||||
has_many :servers, :through => :gather_servers
|
||||
has_many :shoutmsgs, :as => "shoutable"
|
||||
has_many :real_votes, :class_name => "Vote", :as => :votable, :dependent => :destroy
|
||||
|
||||
before_create :init_variables
|
||||
after_create :add_maps_and_server
|
||||
before_save :check_status
|
||||
before_save :check_captains
|
||||
|
||||
def to_s
|
||||
"Gather_#{self.id}"
|
||||
end
|
||||
|
||||
def self.find_game(name)
|
||||
Category.where(name: name, domain: Category::DOMAIN_GAMES).first
|
||||
end
|
||||
|
||||
def self.player_count_for_game(name)
|
||||
game = self.find_game(name)
|
||||
|
||||
if game && players = game.gathers.ordered.first.gatherers
|
||||
players.size
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def demo_name
|
||||
Verification.uncrap("gather-#{self.id}")
|
||||
end
|
||||
|
||||
def states
|
||||
{STATE_RUNNING => "Running", STATE_PICKING => "Picking", STATE_FINISHED => "Finished"}
|
||||
end
|
||||
|
||||
def votes_needed?
|
||||
5
|
||||
end
|
||||
|
||||
def first
|
||||
Gather.where(:category_id => category_id).order("id ASC").first
|
||||
end
|
||||
|
||||
def previous_gather
|
||||
Gather.first(:conditions => ["id < ? AND category_id = ?", self.id, category_id], :order => "id DESC")
|
||||
end
|
||||
|
||||
def next_gather
|
||||
Gather.first(:conditions => ["id > ? AND category_id = ?", self.id, category_id], :order => "id ASC")
|
||||
end
|
||||
|
||||
def last
|
||||
Category.find(category_id).gathers.ordered.first
|
||||
end
|
||||
|
||||
def init_variables
|
||||
self.status = STATE_RUNNING
|
||||
end
|
||||
|
||||
def add_maps_and_server
|
||||
category.maps.basic.classic.each do |m|
|
||||
maps << m
|
||||
end
|
||||
|
||||
(category_id == 44 ? category.servers.hlds.active.ordered : category.servers.active.ordered).each do |s|
|
||||
servers << s
|
||||
end
|
||||
end
|
||||
|
||||
def check_status
|
||||
if status_changed? and status == STATE_PICKING and !self.captain1
|
||||
g = Gather.new
|
||||
g.category = self.category
|
||||
g.save
|
||||
self.captain1 = self.gatherers.most_voted[1]
|
||||
self.captain2 = self.gatherers.most_voted[0]
|
||||
if self.gather_maps.count > 1
|
||||
self.map1 = self.gather_maps.ordered[0]
|
||||
self.map2 = self.gather_maps.ordered[1]
|
||||
elsif self.gather_maps.count > 0
|
||||
self.map1 = self.gather_maps.ordered[0]
|
||||
end
|
||||
if self.gather_servers.count > 0
|
||||
self.server = self.gather_servers.ordered[0].server
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def check_captains
|
||||
if captain1_id_changed? or captain2_id_changed? or admin
|
||||
self.turn = 1
|
||||
self.status = STATE_PICKING
|
||||
gatherers.each do |gatherer|
|
||||
if gatherer.id == captain1_id
|
||||
gatherer.update_attributes(:team => 1, :skip_callbacks => true)
|
||||
elsif gatherer.id == captain2_id
|
||||
gatherer.update_attributes(:team => 2, :skip_callbacks => true)
|
||||
else
|
||||
gatherer.update_attributes(:team => nil, :skip_callbacks => true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def refresh cuser
|
||||
if status == STATE_RUNNING
|
||||
gatherers.idle.destroy_all
|
||||
elsif status == STATE_VOTING and updated_at < 60.seconds.ago and updated_at > 5.days.ago
|
||||
if status == STATE_VOTING and updated_at < 60.seconds.ago
|
||||
self.status = STATE_PICKING
|
||||
save!
|
||||
end
|
||||
elsif status == STATE_PICKING
|
||||
if turn == 1 and gatherers.team(1).count == 2 and gatherers.team(2).count == 1
|
||||
update_attribute :turn, 2
|
||||
elsif turn == 2 and gatherers.team(2).count == 3 and gatherers.team(1).count == 2
|
||||
update_attribute :turn, 1
|
||||
elsif turn == 1 and gatherers.team(1).count == 4 and gatherers.team(2).count == 3
|
||||
update_attribute :turn, 2
|
||||
elsif turn == 2 and gatherers.team(2).count == 5 and gatherers.team(1).count == 4
|
||||
update_attribute :turn, 1
|
||||
elsif turn == 1 and gatherers.team(1).count == 6 and gatherers.team(2).count == 5
|
||||
gatherers.lobby.first.update_attributes(:team => 2, :skip_callbacks => true)
|
||||
update_attribute :turn, 2
|
||||
elsif gatherers.team(1).count == 6 and gatherers.team(2).count == 6
|
||||
update_attribute :status, STATE_FINISHED
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def self.last(name = "NS2")
|
||||
if game = self.find_game(name)
|
||||
game.gathers.ordered.first
|
||||
end
|
||||
end
|
||||
end
|
17
app/models/gather_map.rb
Normal file
17
app/models/gather_map.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
class GatherMap < ActiveRecord::Base
|
||||
scope :ordered, :order => "votes DESC, id DESC"
|
||||
|
||||
belongs_to :gather
|
||||
belongs_to :map
|
||||
has_many :real_votes, :class_name => "Vote", :as => :votable
|
||||
|
||||
before_create :init_variables
|
||||
|
||||
def to_s
|
||||
self.map.to_s
|
||||
end
|
||||
|
||||
def init_variables
|
||||
self.votes = 0
|
||||
end
|
||||
end
|
15
app/models/gather_server.rb
Normal file
15
app/models/gather_server.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
class GatherServer < ActiveRecord::Base
|
||||
scope :ordered, :order => "votes DESC"
|
||||
|
||||
belongs_to :gather
|
||||
belongs_to :server
|
||||
has_many :real_votes, :class_name => "Vote", :as => :votable
|
||||
|
||||
def to_s
|
||||
self.server.to_s
|
||||
end
|
||||
|
||||
def before_create
|
||||
self.votes = 0
|
||||
end
|
||||
end
|
153
app/models/gatherer.rb
Normal file
153
app/models/gatherer.rb
Normal file
|
@ -0,0 +1,153 @@
|
|||
class Gatherer < ActiveRecord::Base
|
||||
IDLE_TIME = 600
|
||||
EJECT_VOTES = 4
|
||||
|
||||
include Extra
|
||||
|
||||
attr_protected :id
|
||||
attr_accessor :confirm, :username
|
||||
cattr_accessor :skip_callbacks
|
||||
|
||||
scope :team,
|
||||
lambda { |team| {:conditions => {:team => team}} }
|
||||
scope :of_user,
|
||||
lambda { |user| {:conditions => {:user_id => user.id}} }
|
||||
scope :lobby, :conditions => "team IS NULL"
|
||||
scope :best,
|
||||
lambda { |gather| {
|
||||
:select => "u.id, u.username, (COUNT(*) / (SELECT COUNT(*) FROM gatherers g3 WHERE g3.user_id = u.id)) AS skill, g4.id",
|
||||
:from => "gathers g1",
|
||||
:joins => "LEFT JOIN gatherers g2 ON g1.captain1_id = g2.id OR g1.captain2_id = g2.id
|
||||
LEFT JOIN users u ON g2.user_id = u.id
|
||||
LEFT JOIN gatherers g4 ON u.id = g4.user_id AND g4.gather_id = #{gather.id}",
|
||||
:group => "u.id",
|
||||
:having => "g4.id IS NOT NULL",
|
||||
:order => "skill DESC",
|
||||
:limit => 15 } }
|
||||
scope :with_kpd,
|
||||
:select => "gatherers.*, SUM(kills)/SUM(deaths) as kpd, COUNT(rounders.id) as rounds",
|
||||
:joins => "LEFT JOIN rounders ON rounders.user_id = gatherers.user_id",
|
||||
:group => "rounders.user_id",
|
||||
:order => "kpd DESC"
|
||||
scope :lobby_team,
|
||||
lambda { |team| {
|
||||
:conditions => ["gatherers.team IS NULL OR gatherers.team = ?", team],
|
||||
:order => "gatherers.team"} }
|
||||
scope :most_voted, :order => "votes DESC, created_at DESC"
|
||||
scope :not_user,
|
||||
lambda { |user| {:conditions => ["user_id != ?", user.id]} }
|
||||
scope :eject_order, :order => "votes ASC"
|
||||
scope :ordered,
|
||||
:joins => "LEFT JOIN gathers ON captain1_id = gatherers.id OR captain2_id = gatherers.id",
|
||||
:order => "captain1_id, captain2_id, gatherers.id"
|
||||
scope :idle,
|
||||
:joins => "LEFT JOIN users ON users.id = gatherers.user_id",
|
||||
:conditions => ["lastvisit < ?", 30.minutes.ago.utc]
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :gather
|
||||
has_many :real_votes, :class_name => "Vote", :as => :votable, :dependent => :destroy
|
||||
|
||||
validates_uniqueness_of :user_id, :scope => :gather_id
|
||||
validates_inclusion_of :team, :in => 1..2, :allow_nil => true
|
||||
validates :confirm, :acceptance => true, :unless => Proc.new {|gatherer| gatherer.user.gatherers.count >= 5}
|
||||
validate :validate_username
|
||||
|
||||
after_create :start_gather, :if => Proc.new {|gatherer| gatherer.gather.gatherers.count == Gather::FULL}
|
||||
after_create :notify_gatherers, :if => Proc.new {|gatherer| gatherer.gather.gatherers.count == Gather::NOTIFY}
|
||||
after_update :change_turn, :unless => Proc.new {|gatherer| gatherer.skip_callbacks == true}
|
||||
after_destroy :cleanup_votes
|
||||
|
||||
def to_s
|
||||
user.to_s
|
||||
end
|
||||
|
||||
def validate_username
|
||||
if username
|
||||
if u = User.first(:conditions => {:username => username})
|
||||
self.user = u
|
||||
else
|
||||
errors.add(:username, t(:gatherer_wrong_username))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def start_gather
|
||||
gather.update_attribute :status, Gather::STATE_VOTING
|
||||
end
|
||||
|
||||
def notify_gatherers
|
||||
Profile.all(:include => :user, :conditions => "notify_gather = 1").each do |p|
|
||||
Notifications.gather p.user, gather if p.user
|
||||
end
|
||||
end
|
||||
|
||||
def change_turn
|
||||
if team_changed? and team != nil
|
||||
new_turn = (team == 1 ? 2 : 1)
|
||||
if team == 2 and [2, 4].include?(gather.gatherers.team(2).count.to_i)
|
||||
new_turn = 2
|
||||
elsif team == 1 and [3, 5].include?(gather.gatherers.team(1).count.to_i)
|
||||
new_turn = 1
|
||||
end
|
||||
gather.update_attribute :turn, new_turn
|
||||
if gather.gatherers.lobby.count == 1
|
||||
gather.gatherers.lobby.first.update_attribute :team, (self.team == 1 ? 2 : 1)
|
||||
end
|
||||
if gather.gatherers.lobby.count == 0
|
||||
gather.update_attribute :status, Gather::STATE_FINISHED
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup_votes
|
||||
gather.map_votes.all(:conditions => {:user_id => user_id}).each { |g| g.destroy }
|
||||
gather.server_votes.all(:conditions => {:user_id => user_id}).each { |g| g.destroy }
|
||||
gather.gatherer_votes.all(:conditions => {:user_id => user_id}).each { |g| g.destroy }
|
||||
end
|
||||
|
||||
def votes_needed?
|
||||
return 5
|
||||
end
|
||||
|
||||
def captain?
|
||||
gather.captain1 == self or gather.captain2 == self
|
||||
end
|
||||
|
||||
def turn?
|
||||
(gather.captain1 == self and gather.turn == 1) or (gather.captain2 == self and gather.turn == 2)
|
||||
end
|
||||
|
||||
def can_create? cuser, params = {}
|
||||
# and check_params(params, [:user_id, :gather_id])
|
||||
cuser \
|
||||
and user == cuser \
|
||||
and !cuser.banned?(Ban::TYPE_GATHER) \
|
||||
and gather.status == Gather::STATE_RUNNING \
|
||||
and gather.gatherers.count < Gather::FULL \
|
||||
and !gather.gatherers.of_user(cuser).first
|
||||
end
|
||||
|
||||
def can_update? cuser, params = {}
|
||||
return false unless cuser
|
||||
if params.keys.include? "username"
|
||||
if cuser.admin?
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
return false unless team.nil? \
|
||||
and ((gather.captain1.user == cuser and gather.turn == 1) or (gather.captain2.user == cuser and gather.turn == 2))
|
||||
return false if gather.turn == 1 and gather.gatherers.team(1).count == 2 and gather.gatherers.team(2).count < 3
|
||||
return false if gather.turn == 2 and gather.gatherers.team(1).count < 4 and gather.gatherers.team(2).count == 3
|
||||
return false if gather.turn == 1 and gather.gatherers.team(1).count == 4 and gather.gatherers.team(2).count < 5
|
||||
return false if gather.turn == 2 and gather.gatherers.team(1).count < 6 and gather.gatherers.team(2).count == 5
|
||||
return false if gather.turn == 1 and gather.gatherers.team(1).count == 6
|
||||
true
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and ((user == cuser or cuser.admin?) and gather.status == Gather::STATE_RUNNING)
|
||||
end
|
||||
end
|
77
app/models/group.rb
Normal file
77
app/models/group.rb
Normal file
|
@ -0,0 +1,77 @@
|
|||
class Group < ActiveRecord::Base
|
||||
include Extra
|
||||
|
||||
ADMINS = 1
|
||||
REFEREES = 2
|
||||
MOVIES = 3
|
||||
DONORS = 4
|
||||
MOVIEMAKERS = 5
|
||||
SHOUTCASTERS = 6
|
||||
CHAMPIONS = 7
|
||||
PREDICTORS = 8
|
||||
STAFF = 10
|
||||
|
||||
attr_protected :id, :updated_at, :created_at, :founder_id
|
||||
validates_length_of :name, :maximum => 20
|
||||
|
||||
has_and_belongs_to_many :users
|
||||
has_many :groupers
|
||||
has_many :users, :through => :groupers
|
||||
belongs_to :founder, :class_name => "User"
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def self.staff
|
||||
staff = []
|
||||
(find(ADMINS).groupers + find(PREDICTORS).groupers + find(SHOUTCASTERS).groupers + find(STAFF).groupers + find(REFEREES).groupers).each do |g|
|
||||
staff << g unless staff.include? g
|
||||
end
|
||||
staff
|
||||
end
|
||||
|
||||
def self.admins
|
||||
admins = []
|
||||
(find(ADMINS).groupers).each do |g|
|
||||
admins << g unless admins.include? g
|
||||
end
|
||||
admins
|
||||
end
|
||||
|
||||
def self.referees
|
||||
referees = []
|
||||
(find(REFEREES).groupers).each do |g|
|
||||
referees << g unless referees.include? g
|
||||
end
|
||||
referees
|
||||
end
|
||||
|
||||
def self.extras
|
||||
extras = []
|
||||
(find(PREDICTORS).groupers + find(STAFF).groupers).each do |g|
|
||||
extras << g unless extras.include? g
|
||||
end
|
||||
extras
|
||||
end
|
||||
|
||||
def self.shoutcasters
|
||||
shoutcasters = []
|
||||
(find(SHOUTCASTERS).groupers).each do |g|
|
||||
shoutcasters << g unless shoutcasters.include? g
|
||||
end
|
||||
shoutcasters
|
||||
end
|
||||
end
|
33
app/models/grouper.rb
Normal file
33
app/models/grouper.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
class Grouper < ActiveRecord::Base
|
||||
attr_protected :id, :created_at, :updated_at
|
||||
attr_accessor :username
|
||||
|
||||
belongs_to :group
|
||||
belongs_to :user
|
||||
|
||||
validates_associated :group, :user
|
||||
validates :group, :user, :presence => true
|
||||
validates :task, :length => {:maximum => 25}
|
||||
|
||||
before_validation :fetch_user, :if => Proc.new {|grouper| grouper.username and !grouper.username.empty?}
|
||||
|
||||
def to_s
|
||||
user.to_s
|
||||
end
|
||||
|
||||
def fetch_user
|
||||
self.user = User.find_by_username(username)
|
||||
end
|
||||
|
||||
def can_create? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_update? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
|
||||
def can_destroy? cuser
|
||||
cuser and cuser.admin?
|
||||
end
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue