forked from OpenNeo/impress
Merge branch 'main' into devcontainer
This commit is contained in:
commit
793c2c0451
158 changed files with 411 additions and 1251 deletions
13
Gemfile
13
Gemfile
|
@ -1,7 +1,7 @@
|
||||||
source 'http://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
ruby '3.1.4'
|
ruby '3.1.4'
|
||||||
|
|
||||||
gem 'rails', '= 7.0.7.1'
|
gem 'rails', '~> 7.1', '>= 7.1.1'
|
||||||
|
|
||||||
# The HTTP server running the Rails instance.
|
# The HTTP server running the Rails instance.
|
||||||
gem 'puma', '~> 6.3', '>= 6.3.1'
|
gem 'puma', '~> 6.3', '>= 6.3.1'
|
||||||
|
@ -54,6 +54,9 @@ gem 'letter_opener', '~> 1.8', '>= 1.8.1', group: :development
|
||||||
# For parallel API calls.
|
# For parallel API calls.
|
||||||
gem 'parallel', '~> 1.23'
|
gem 'parallel', '~> 1.23'
|
||||||
|
|
||||||
|
# For miscellaneous HTTP requests.
|
||||||
|
gem "httparty", "~> 0.21.0"
|
||||||
|
|
||||||
# For debugging.
|
# For debugging.
|
||||||
gem 'web-console', '~> 4.2', group: :development
|
gem 'web-console', '~> 4.2', group: :development
|
||||||
|
|
||||||
|
@ -62,9 +65,3 @@ gem 'record_tag_helper', '~> 1.0', '>= 1.0.1'
|
||||||
|
|
||||||
# Reduces boot times through caching; required in config/boot.rb
|
# Reduces boot times through caching; required in config/boot.rb
|
||||||
gem 'bootsnap', '~> 1.16', require: false
|
gem 'bootsnap', '~> 1.16', require: false
|
||||||
|
|
||||||
# For testing.
|
|
||||||
group :test do
|
|
||||||
gem 'factory_girl_rails', '~> 4.9'
|
|
||||||
gem 'rspec-rails', '~> 2.0.0.beta.22'
|
|
||||||
end
|
|
||||||
|
|
198
Gemfile.lock
198
Gemfile.lock
|
@ -5,72 +5,80 @@ GIT
|
||||||
RocketAMF (1.0.0)
|
RocketAMF (1.0.0)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: http://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (7.0.7.1)
|
actioncable (7.1.1)
|
||||||
actionpack (= 7.0.7.1)
|
actionpack (= 7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activesupport (= 7.1.1)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
actionmailbox (7.0.7.1)
|
zeitwerk (~> 2.6)
|
||||||
actionpack (= 7.0.7.1)
|
actionmailbox (7.1.1)
|
||||||
activejob (= 7.0.7.1)
|
actionpack (= 7.1.1)
|
||||||
activerecord (= 7.0.7.1)
|
activejob (= 7.1.1)
|
||||||
activestorage (= 7.0.7.1)
|
activerecord (= 7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activestorage (= 7.1.1)
|
||||||
|
activesupport (= 7.1.1)
|
||||||
mail (>= 2.7.1)
|
mail (>= 2.7.1)
|
||||||
net-imap
|
net-imap
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
actionmailer (7.0.7.1)
|
actionmailer (7.1.1)
|
||||||
actionpack (= 7.0.7.1)
|
actionpack (= 7.1.1)
|
||||||
actionview (= 7.0.7.1)
|
actionview (= 7.1.1)
|
||||||
activejob (= 7.0.7.1)
|
activejob (= 7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activesupport (= 7.1.1)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
net-imap
|
net-imap
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.2)
|
||||||
actionpack (7.0.7.1)
|
actionpack (7.1.1)
|
||||||
actionview (= 7.0.7.1)
|
actionview (= 7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activesupport (= 7.1.1)
|
||||||
rack (~> 2.0, >= 2.2.4)
|
nokogiri (>= 1.8.5)
|
||||||
|
rack (>= 2.2.4)
|
||||||
|
rack-session (>= 1.0.1)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
rails-html-sanitizer (~> 1.6)
|
||||||
actiontext (7.0.7.1)
|
actiontext (7.1.1)
|
||||||
actionpack (= 7.0.7.1)
|
actionpack (= 7.1.1)
|
||||||
activerecord (= 7.0.7.1)
|
activerecord (= 7.1.1)
|
||||||
activestorage (= 7.0.7.1)
|
activestorage (= 7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activesupport (= 7.1.1)
|
||||||
globalid (>= 0.6.0)
|
globalid (>= 0.6.0)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (7.0.7.1)
|
actionview (7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activesupport (= 7.1.1)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.11)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
rails-html-sanitizer (~> 1.6)
|
||||||
activejob (7.0.7.1)
|
activejob (7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activesupport (= 7.1.1)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (7.0.7.1)
|
activemodel (7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activesupport (= 7.1.1)
|
||||||
activerecord (7.0.7.1)
|
activerecord (7.1.1)
|
||||||
activemodel (= 7.0.7.1)
|
activemodel (= 7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activesupport (= 7.1.1)
|
||||||
activestorage (7.0.7.1)
|
timeout (>= 0.4.0)
|
||||||
actionpack (= 7.0.7.1)
|
activestorage (7.1.1)
|
||||||
activejob (= 7.0.7.1)
|
actionpack (= 7.1.1)
|
||||||
activerecord (= 7.0.7.1)
|
activejob (= 7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activerecord (= 7.1.1)
|
||||||
|
activesupport (= 7.1.1)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
mini_mime (>= 1.1.0)
|
activesupport (7.1.1)
|
||||||
activesupport (7.0.7.1)
|
base64
|
||||||
|
bigdecimal
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
|
connection_pool (>= 2.2.5)
|
||||||
|
drb
|
||||||
i18n (>= 1.6, < 2)
|
i18n (>= 1.6, < 2)
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
|
mutex_m
|
||||||
tzinfo (~> 2.0)
|
tzinfo (~> 2.0)
|
||||||
addressable (2.8.4)
|
addressable (2.8.4)
|
||||||
public_suffix (>= 2.0.2, < 6.0)
|
public_suffix (>= 2.0.2, < 6.0)
|
||||||
|
@ -78,7 +86,9 @@ GEM
|
||||||
babel-transpiler (0.7.0)
|
babel-transpiler (0.7.0)
|
||||||
babel-source (>= 4.0, < 6)
|
babel-source (>= 4.0, < 6)
|
||||||
execjs (~> 2.0)
|
execjs (~> 2.0)
|
||||||
|
base64 (0.1.1)
|
||||||
bcrypt (3.1.19)
|
bcrypt (3.1.19)
|
||||||
|
bigdecimal (3.1.4)
|
||||||
bindex (0.8.1)
|
bindex (0.8.1)
|
||||||
bootsnap (1.16.0)
|
bootsnap (1.16.0)
|
||||||
msgpack (~> 1.2)
|
msgpack (~> 1.2)
|
||||||
|
@ -87,7 +97,7 @@ GEM
|
||||||
connection_pool (2.2.5)
|
connection_pool (2.2.5)
|
||||||
crass (1.0.6)
|
crass (1.0.6)
|
||||||
date (3.3.3)
|
date (3.3.3)
|
||||||
devise (4.9.2)
|
devise (4.9.3)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (>= 4.1.0)
|
railties (>= 4.1.0)
|
||||||
|
@ -95,20 +105,16 @@ GEM
|
||||||
warden (~> 1.2.3)
|
warden (~> 1.2.3)
|
||||||
devise-encryptable (0.2.0)
|
devise-encryptable (0.2.0)
|
||||||
devise (>= 2.1.0)
|
devise (>= 2.1.0)
|
||||||
diff-lcs (1.2.5)
|
|
||||||
domain_name (0.5.20190701)
|
domain_name (0.5.20190701)
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
dotenv (2.8.1)
|
dotenv (2.8.1)
|
||||||
dotenv-rails (2.8.1)
|
dotenv-rails (2.8.1)
|
||||||
dotenv (= 2.8.1)
|
dotenv (= 2.8.1)
|
||||||
railties (>= 3.2)
|
railties (>= 3.2)
|
||||||
|
drb (2.1.1)
|
||||||
|
ruby2_keywords
|
||||||
erubi (1.12.0)
|
erubi (1.12.0)
|
||||||
execjs (2.5.2)
|
execjs (2.5.2)
|
||||||
factory_girl (4.9.0)
|
|
||||||
activesupport (>= 3.0.0)
|
|
||||||
factory_girl_rails (4.9.0)
|
|
||||||
factory_girl (~> 4.9.0)
|
|
||||||
railties (>= 3.0.0)
|
|
||||||
ffi (1.15.5)
|
ffi (1.15.5)
|
||||||
globalid (1.2.1)
|
globalid (1.2.1)
|
||||||
activesupport (>= 6.1)
|
activesupport (>= 6.1)
|
||||||
|
@ -124,9 +130,16 @@ GEM
|
||||||
http-cookie (1.0.5)
|
http-cookie (1.0.5)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
http_accept_language (2.1.1)
|
http_accept_language (2.1.1)
|
||||||
|
httparty (0.21.0)
|
||||||
|
mini_mime (>= 1.0.0)
|
||||||
|
multi_xml (>= 0.5.2)
|
||||||
i18n (1.14.1)
|
i18n (1.14.1)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
jsbundling-rails (1.1.2)
|
io-console (0.6.0)
|
||||||
|
irb (1.8.3)
|
||||||
|
rdoc
|
||||||
|
reline (>= 0.3.8)
|
||||||
|
jsbundling-rails (1.2.1)
|
||||||
railties (>= 6.0.0)
|
railties (>= 6.0.0)
|
||||||
launchy (2.5.2)
|
launchy (2.5.2)
|
||||||
addressable (~> 2.8)
|
addressable (~> 2.8)
|
||||||
|
@ -141,7 +154,6 @@ GEM
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
marcel (1.0.2)
|
marcel (1.0.2)
|
||||||
method_source (1.0.0)
|
|
||||||
mime-types (3.4.1)
|
mime-types (3.4.1)
|
||||||
mime-types-data (~> 3.2015)
|
mime-types-data (~> 3.2015)
|
||||||
mime-types-data (3.2023.0218.1)
|
mime-types-data (3.2023.0218.1)
|
||||||
|
@ -149,6 +161,8 @@ GEM
|
||||||
mini_portile2 (2.8.4)
|
mini_portile2 (2.8.4)
|
||||||
minitest (5.19.0)
|
minitest (5.19.0)
|
||||||
msgpack (1.7.2)
|
msgpack (1.7.2)
|
||||||
|
multi_xml (0.6.0)
|
||||||
|
mutex_m (0.1.2)
|
||||||
mysql2 (0.5.5)
|
mysql2 (0.5.5)
|
||||||
net-imap (0.4.2)
|
net-imap (0.4.2)
|
||||||
date
|
date
|
||||||
|
@ -166,6 +180,8 @@ GEM
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
parallel (1.23.0)
|
parallel (1.23.0)
|
||||||
|
psych (5.1.1.1)
|
||||||
|
stringio
|
||||||
public_suffix (5.0.3)
|
public_suffix (5.0.3)
|
||||||
puma (6.4.0)
|
puma (6.4.0)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
|
@ -173,22 +189,27 @@ GEM
|
||||||
rack (2.2.8)
|
rack (2.2.8)
|
||||||
rack-attack (6.7.0)
|
rack-attack (6.7.0)
|
||||||
rack (>= 1.0, < 4)
|
rack (>= 1.0, < 4)
|
||||||
|
rack-session (1.0.1)
|
||||||
|
rack (< 3)
|
||||||
rack-test (2.1.0)
|
rack-test (2.1.0)
|
||||||
rack (>= 1.3)
|
rack (>= 1.3)
|
||||||
rails (7.0.7.1)
|
rackup (1.0.0)
|
||||||
actioncable (= 7.0.7.1)
|
rack (< 3)
|
||||||
actionmailbox (= 7.0.7.1)
|
webrick
|
||||||
actionmailer (= 7.0.7.1)
|
rails (7.1.1)
|
||||||
actionpack (= 7.0.7.1)
|
actioncable (= 7.1.1)
|
||||||
actiontext (= 7.0.7.1)
|
actionmailbox (= 7.1.1)
|
||||||
actionview (= 7.0.7.1)
|
actionmailer (= 7.1.1)
|
||||||
activejob (= 7.0.7.1)
|
actionpack (= 7.1.1)
|
||||||
activemodel (= 7.0.7.1)
|
actiontext (= 7.1.1)
|
||||||
activerecord (= 7.0.7.1)
|
actionview (= 7.1.1)
|
||||||
activestorage (= 7.0.7.1)
|
activejob (= 7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activemodel (= 7.1.1)
|
||||||
|
activerecord (= 7.1.1)
|
||||||
|
activestorage (= 7.1.1)
|
||||||
|
activesupport (= 7.1.1)
|
||||||
bundler (>= 1.15.0)
|
bundler (>= 1.15.0)
|
||||||
railties (= 7.0.7.1)
|
railties (= 7.1.1)
|
||||||
rails-dom-testing (2.2.0)
|
rails-dom-testing (2.2.0)
|
||||||
activesupport (>= 5.0.0)
|
activesupport (>= 5.0.0)
|
||||||
minitest
|
minitest
|
||||||
|
@ -196,18 +217,21 @@ GEM
|
||||||
rails-html-sanitizer (1.6.0)
|
rails-html-sanitizer (1.6.0)
|
||||||
loofah (~> 2.21)
|
loofah (~> 2.21)
|
||||||
nokogiri (~> 1.14)
|
nokogiri (~> 1.14)
|
||||||
rails-i18n (7.0.7)
|
rails-i18n (7.0.8)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
railties (>= 6.0.0, < 8)
|
railties (>= 6.0.0, < 8)
|
||||||
railties (7.0.7.1)
|
railties (7.1.1)
|
||||||
actionpack (= 7.0.7.1)
|
actionpack (= 7.1.1)
|
||||||
activesupport (= 7.0.7.1)
|
activesupport (= 7.1.1)
|
||||||
method_source
|
irb
|
||||||
|
rackup (>= 1.0.0)
|
||||||
rake (>= 12.2)
|
rake (>= 12.2)
|
||||||
thor (~> 1.0)
|
thor (~> 1.0, >= 1.2.2)
|
||||||
zeitwerk (~> 2.5)
|
zeitwerk (~> 2.6)
|
||||||
rake (13.0.6)
|
rake (13.0.6)
|
||||||
rdiscount (2.2.7.1)
|
rdiscount (2.2.7.1)
|
||||||
|
rdoc (6.5.0)
|
||||||
|
psych (>= 4.0.0)
|
||||||
react-rails (2.7.1)
|
react-rails (2.7.1)
|
||||||
babel-transpiler (>= 0.7.0)
|
babel-transpiler (>= 0.7.0)
|
||||||
connection_pool
|
connection_pool
|
||||||
|
@ -216,9 +240,11 @@ GEM
|
||||||
tilt
|
tilt
|
||||||
record_tag_helper (1.0.1)
|
record_tag_helper (1.0.1)
|
||||||
actionview (>= 5)
|
actionview (>= 5)
|
||||||
|
reline (0.3.9)
|
||||||
|
io-console (~> 0.5)
|
||||||
request_store (1.5.1)
|
request_store (1.5.1)
|
||||||
rack (>= 1.4)
|
rack (>= 1.4)
|
||||||
responders (3.1.0)
|
responders (3.1.1)
|
||||||
actionpack (>= 5.2)
|
actionpack (>= 5.2)
|
||||||
railties (>= 5.2)
|
railties (>= 5.2)
|
||||||
rest-client (2.1.0)
|
rest-client (2.1.0)
|
||||||
|
@ -226,18 +252,7 @@ GEM
|
||||||
http-cookie (>= 1.0.2, < 2.0)
|
http-cookie (>= 1.0.2, < 2.0)
|
||||||
mime-types (>= 1.16, < 4.0)
|
mime-types (>= 1.16, < 4.0)
|
||||||
netrc (~> 0.8)
|
netrc (~> 0.8)
|
||||||
rspec (2.0.1)
|
ruby2_keywords (0.0.5)
|
||||||
rspec-core (~> 2.0.1)
|
|
||||||
rspec-expectations (~> 2.0.1)
|
|
||||||
rspec-mocks (~> 2.0.1)
|
|
||||||
rspec-core (2.0.1)
|
|
||||||
rspec-expectations (2.0.1)
|
|
||||||
diff-lcs (>= 1.1.2)
|
|
||||||
rspec-mocks (2.0.1)
|
|
||||||
rspec-core (~> 2.0.1)
|
|
||||||
rspec-expectations (~> 2.0.1)
|
|
||||||
rspec-rails (2.0.1)
|
|
||||||
rspec (~> 2.0.0)
|
|
||||||
sanitize (6.0.2)
|
sanitize (6.0.2)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.12.0)
|
nokogiri (>= 1.12.0)
|
||||||
|
@ -258,6 +273,7 @@ GEM
|
||||||
actionpack (>= 5.2)
|
actionpack (>= 5.2)
|
||||||
activesupport (>= 5.2)
|
activesupport (>= 5.2)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
|
stringio (3.0.8)
|
||||||
temple (0.8.2)
|
temple (0.8.2)
|
||||||
terser (1.1.17)
|
terser (1.1.17)
|
||||||
execjs (>= 0.3.0, < 3)
|
execjs (>= 0.3.0, < 3)
|
||||||
|
@ -276,6 +292,7 @@ GEM
|
||||||
activemodel (>= 6.0.0)
|
activemodel (>= 6.0.0)
|
||||||
bindex (>= 0.4.0)
|
bindex (>= 0.4.0)
|
||||||
railties (>= 6.0.0)
|
railties (>= 6.0.0)
|
||||||
|
webrick (1.8.1)
|
||||||
websocket-driver (0.7.6)
|
websocket-driver (0.7.6)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.5)
|
websocket-extensions (0.1.5)
|
||||||
|
@ -291,10 +308,10 @@ DEPENDENCIES
|
||||||
devise (~> 4.9, >= 4.9.2)
|
devise (~> 4.9, >= 4.9.2)
|
||||||
devise-encryptable (~> 0.2.0)
|
devise-encryptable (~> 0.2.0)
|
||||||
dotenv-rails (~> 2.8, >= 2.8.1)
|
dotenv-rails (~> 2.8, >= 2.8.1)
|
||||||
factory_girl_rails (~> 4.9)
|
|
||||||
globalize (~> 6.2, >= 6.2.1)
|
globalize (~> 6.2, >= 6.2.1)
|
||||||
haml (~> 6.1, >= 6.1.1)
|
haml (~> 6.1, >= 6.1.1)
|
||||||
http_accept_language (~> 2.1, >= 2.1.1)
|
http_accept_language (~> 2.1, >= 2.1.1)
|
||||||
|
httparty (~> 0.21.0)
|
||||||
jsbundling-rails (~> 1.1)
|
jsbundling-rails (~> 1.1)
|
||||||
letter_opener (~> 1.8, >= 1.8.1)
|
letter_opener (~> 1.8, >= 1.8.1)
|
||||||
mysql2 (~> 0.5.5)
|
mysql2 (~> 0.5.5)
|
||||||
|
@ -302,13 +319,12 @@ DEPENDENCIES
|
||||||
parallel (~> 1.23)
|
parallel (~> 1.23)
|
||||||
puma (~> 6.3, >= 6.3.1)
|
puma (~> 6.3, >= 6.3.1)
|
||||||
rack-attack (~> 6.7)
|
rack-attack (~> 6.7)
|
||||||
rails (= 7.0.7.1)
|
rails (~> 7.1, >= 7.1.1)
|
||||||
rails-i18n (~> 7.0, >= 7.0.7)
|
rails-i18n (~> 7.0, >= 7.0.7)
|
||||||
rdiscount (~> 2.2, >= 2.2.7.1)
|
rdiscount (~> 2.2, >= 2.2.7.1)
|
||||||
react-rails (~> 2.7, >= 2.7.1)
|
react-rails (~> 2.7, >= 2.7.1)
|
||||||
record_tag_helper (~> 1.0, >= 1.0.1)
|
record_tag_helper (~> 1.0, >= 1.0.1)
|
||||||
rest-client (~> 2.1)
|
rest-client (~> 2.1)
|
||||||
rspec-rails (~> 2.0.0.beta.22)
|
|
||||||
sanitize (~> 6.0, >= 6.0.2)
|
sanitize (~> 6.0, >= 6.0.2)
|
||||||
sass-rails (~> 6.0)
|
sass-rails (~> 6.0)
|
||||||
sprockets (~> 4.2)
|
sprockets (~> 4.2)
|
||||||
|
|
8
README
8
README
|
@ -1,8 +0,0 @@
|
||||||
An extension of Dress to Impress (PHP) that runs on Ruby on Rails.
|
|
||||||
I wanted to use Rails initially for Impress, but hoped that using
|
|
||||||
PHP would allow me to attract more developers. Looks like that
|
|
||||||
wasn't the case, so I just went with what I loved and made the
|
|
||||||
items database in Rails.
|
|
||||||
|
|
||||||
Future Impress sections will likely find themselves in this
|
|
||||||
project, rather than the PHP project.
|
|
7
README.md
Normal file
7
README.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<img src="https://i.imgur.com/mZ2FCfX.png" width="200" height="200" alt="Dress to Impress beach logo" />
|
||||||
|
|
||||||
|
# Dress to Impress
|
||||||
|
|
||||||
|
Oh! We've been revitalizing the Rails app! Fun!
|
||||||
|
|
||||||
|
There'll be more to say about it here soon :3
|
10
app/assets/javascripts/ZeroClipboard.min.js
vendored
10
app/assets/javascripts/ZeroClipboard.min.js
vendored
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -344,7 +344,7 @@ var Neopia = (function ($, I18n) {
|
||||||
}
|
}
|
||||||
var itemName = this.props.item.name;
|
var itemName = this.props.item.name;
|
||||||
var imageSrc =
|
var imageSrc =
|
||||||
"http://pets.neopets.com/cpn/" +
|
"https://pets.neopets.com/cpn/" +
|
||||||
petName +
|
petName +
|
||||||
"/1/1.png?" +
|
"/1/1.png?" +
|
||||||
this.appearanceQuery();
|
this.appearanceQuery();
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
function loadNotable() {
|
function loadNotable() {
|
||||||
// TODO: add HTTPS to notables
|
// TODO: add HTTPS to notables
|
||||||
// $.getJSON('http://notables.openneo.net/api/1/days/ago/1?callback=?', function (response) {
|
// $.getJSON('https://notables.openneo.net/api/1/days/ago/1?callback=?', function (response) {
|
||||||
// var notables = response.notables;
|
// var notables = response.notables;
|
||||||
// var i = Math.floor(Math.random() * notables.length);
|
// var i = Math.floor(Math.random() * notables.length);
|
||||||
// Preview.Job.fallback = new Preview.Job.Name(notables[i].petName);
|
// Preview.Job.fallback = new Preview.Job.Name(notables[i].petName);
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
// lol lazy code for prank image :P
|
// lol lazy code for prank image :P
|
||||||
// TODO: HTTPS?
|
// TODO: HTTPS?
|
||||||
return (
|
return (
|
||||||
"http://swfimages.impress.openneo.net" +
|
"https://swfimages.impress.openneo.net" +
|
||||||
"/biology/000/000/0-2/" +
|
"/biology/000/000/0-2/" +
|
||||||
key.substr(2) +
|
key.substr(2) +
|
||||||
"/300x300.png"
|
"/300x300.png"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
function petImage(id, size) {
|
function petImage(id, size) {
|
||||||
return 'http://pets.neopets.com/' + id + '/1/' + size + '.png';
|
return 'https://pets.neopets.com/' + id + '/1/' + size + '.png';
|
||||||
}
|
}
|
||||||
|
|
||||||
var PetQuery = {},
|
var PetQuery = {},
|
||||||
|
|
|
@ -63,7 +63,7 @@ var DEBUG = (document.location.search.substr(0, 6) == '?debug');
|
||||||
}
|
}
|
||||||
|
|
||||||
function petThumbnailUrl(pet_name) {
|
function petThumbnailUrl(pet_name) {
|
||||||
return 'http://pets.neopets.com/cpn/' + pet_name + '/1/1.png';
|
return 'https://pets.neopets.com/cpn/' + pet_name + '/1/1.png';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Items */
|
/* Items */
|
||||||
|
|
|
@ -191,7 +191,7 @@ body.campaigns-show, body.campaigns-current
|
||||||
width: $outfit-inner-width
|
width: $outfit-inner-width
|
||||||
|
|
||||||
&.banner
|
&.banner
|
||||||
background-image: url(http://images.neopets.com/themes/004_bir_a2e60/footer_bg.png)
|
background-image: url(https://images.neopets.com/themes/004_bir_a2e60/footer_bg.png)
|
||||||
background-position: 0 -60px
|
background-position: 0 -60px
|
||||||
border: 2px solid #006
|
border: 2px solid #006
|
||||||
color: white
|
color: white
|
||||||
|
|
|
@ -41,11 +41,6 @@ class ApplicationController < ActionController::Base
|
||||||
I18n.default_locale
|
I18n.default_locale
|
||||||
end
|
end
|
||||||
|
|
||||||
def localized_fragment_exist?(key)
|
|
||||||
localized_key = localize_fragment_key(key, locale)
|
|
||||||
fragment_exist?(localized_key)
|
|
||||||
end
|
|
||||||
|
|
||||||
def not_found(record_name='record')
|
def not_found(record_name='record')
|
||||||
raise ActionController::RoutingError.new("#{record_name} not found")
|
raise ActionController::RoutingError.new("#{record_name} not found")
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
class SweeperController < ActionController::Base
|
|
||||||
def expire_action_proxy(options)
|
|
||||||
options[:only_path] = true
|
|
||||||
path = Rails.application.routes.url_helpers.url_for(options)
|
|
||||||
fragment_name = "#{LocalImpressHost}#{path}"
|
|
||||||
expire_fragment(fragment_name)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -92,13 +92,9 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
JAVASCRIPT_LIBRARIES = {
|
JAVASCRIPT_LIBRARIES = {
|
||||||
:addthis => '//s7.addthis.com/js/250/addthis_widget.js#username=openneo',
|
:jquery => 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js',
|
||||||
:bitly => '//bit.ly/javascript-api.js?version=latest&login=openneo&apiKey=R_4d0438829b7a99860de1d3edf55d8dc8',
|
:jquery20 => 'https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js',
|
||||||
:html5 => '//html5shim.googlecode.com/svn/trunk/html5.js',
|
:jquery_tmpl => 'https://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js',
|
||||||
:jquery => '//ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js',
|
|
||||||
:jquery20 => '//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js',
|
|
||||||
:jquery_tmpl => '//ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js',
|
|
||||||
:swfobject => '//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def include_javascript_libraries(*library_names)
|
def include_javascript_libraries(*library_names)
|
||||||
|
|
|
@ -13,11 +13,11 @@ module ClosetHangersHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_neomail_url(neopets_username)
|
def send_neomail_url(neopets_username)
|
||||||
"http://www.neopets.com/neomessages.phtml?type=send&recipient=#{CGI.escape neopets_username}"
|
"https://www.neopets.com/neomessages.phtml?type=send&recipient=#{CGI.escape neopets_username}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def neopets_lookup_url(neopets_username)
|
def neopets_lookup_url(neopets_username)
|
||||||
"http://www.neopets.com/userlookup.phtml?user=#{CGI.escape neopets_username}"
|
"https://www.neopets.com/userlookup.phtml?user=#{CGI.escape neopets_username}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def hangers_group_visibility_field_name(owned)
|
def hangers_group_visibility_field_name(owned)
|
||||||
|
@ -75,7 +75,7 @@ module ClosetHangersHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def nc_icon_url
|
def nc_icon_url
|
||||||
"http://#{request.host}#{image_path 'nc.png'}"
|
"https://#{request.host}#{image_path 'nc.png'}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def petpage_closet_list_checked(closet_list, owned)
|
def petpage_closet_list_checked(closet_list, owned)
|
||||||
|
|
|
@ -4,7 +4,7 @@ module ClosetPagesHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def neopets_login_url
|
def neopets_login_url
|
||||||
"http://www.neopets.com/loginpage.phtml"
|
"https://www.neopets.com/loginpage.phtml"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ module ContributionHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
PET_TYPE_IMAGE_FORMAT = 'http://pets.neopets.com/cp/%s/1/3.png'
|
PET_TYPE_IMAGE_FORMAT = 'https://pets.neopets.com/cp/%s/1/3.png'
|
||||||
def contributed_pet_type(main_key, pet_type, show_image)
|
def contributed_pet_type(main_key, pet_type, show_image)
|
||||||
span = content_tag(:span, pet_type.human_name, :class => 'contributed-name')
|
span = content_tag(:span, pet_type.human_name, :class => 'contributed-name')
|
||||||
description = translate('contributions.contributed_description.parents.pet_type_html',
|
description = translate('contributions.contributed_description.parents.pet_type_html',
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
module DonationsHelper
|
module DonationsHelper
|
||||||
THANK_YOU_GREETINGS = [
|
THANK_YOU_GREETINGS = [
|
||||||
'http://images.neopets.com/new_greetings/1368.gif',
|
'https://images.neopets.com/new_greetings/1368.gif',
|
||||||
'http://images.neopets.com/new_greetings/466.gif',
|
'https://images.neopets.com/new_greetings/466.gif',
|
||||||
'http://images.neopets.com/new_greetings/48.gif',
|
'https://images.neopets.com/new_greetings/48.gif',
|
||||||
'http://images.neopets.com/new_greetings/49.gif',
|
'https://images.neopets.com/new_greetings/49.gif',
|
||||||
'http://images.neopets.com/new_greetings/64.gif',
|
'https://images.neopets.com/new_greetings/64.gif',
|
||||||
'http://images.neopets.com/new_greetings/65.gif',
|
'https://images.neopets.com/new_greetings/65.gif',
|
||||||
'http://images.neopets.com/new_greetings/66.gif',
|
'https://images.neopets.com/new_greetings/66.gif',
|
||||||
'http://images.neopets.com/new_greetings/67.gif',
|
'https://images.neopets.com/new_greetings/67.gif',
|
||||||
'http://images.neopets.com/new_greetings/69.gif',
|
'https://images.neopets.com/new_greetings/69.gif',
|
||||||
'http://images.neopets.com/new_greetings/71.gif',
|
'https://images.neopets.com/new_greetings/71.gif',
|
||||||
'http://images.neopets.com/new_greetings/72.gif',
|
'https://images.neopets.com/new_greetings/72.gif',
|
||||||
'http://images.neopets.com/new_greetings/103.gif',
|
'https://images.neopets.com/new_greetings/103.gif',
|
||||||
'http://images.neopets.com/new_greetings/420.gif'
|
'https://images.neopets.com/new_greetings/420.gif'
|
||||||
]
|
]
|
||||||
|
|
||||||
def thank_you_greeting_url
|
def thank_you_greeting_url
|
||||||
|
|
|
@ -2,7 +2,7 @@ module ItemsHelper
|
||||||
JNItemsURLFormat = 'https://items.jellyneo.net/search/?name=%s&name_type=3'
|
JNItemsURLFormat = 'https://items.jellyneo.net/search/?name=%s&name_type=3'
|
||||||
|
|
||||||
module PetTypeImage
|
module PetTypeImage
|
||||||
Format = 'http://pets.neopets.com/cp/%s/%i/%i.png'
|
Format = 'https://pets.neopets.com/cp/%s/%i/%i.png'
|
||||||
|
|
||||||
Emotions = {
|
Emotions = {
|
||||||
:happy => 1,
|
:happy => 1,
|
||||||
|
@ -85,19 +85,19 @@ module ItemsHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def shop_wizard_url_for(item)
|
def shop_wizard_url_for(item)
|
||||||
"http://www.neopets.com/market.phtml?type=wizard&string=#{CGI::escape item.name}"
|
"https://www.neopets.com/market.phtml?type=wizard&string=#{CGI::escape item.name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def super_shop_wizard_url_for(item)
|
def super_shop_wizard_url_for(item)
|
||||||
"http://www.neopets.com/portal/supershopwiz.phtml?string=#{CGI::escape item.name}"
|
"https://www.neopets.com/portal/supershopwiz.phtml?string=#{CGI::escape item.name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def trading_post_url_for(item)
|
def trading_post_url_for(item)
|
||||||
"http://www.neopets.com/island/tradingpost.phtml?type=browse&criteria=item_exact&search_string=#{CGI::escape item.name}"
|
"https://www.neopets.com/island/tradingpost.phtml?type=browse&criteria=item_exact&search_string=#{CGI::escape item.name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def auction_genie_url_for(item)
|
def auction_genie_url_for(item)
|
||||||
"http://www.neopets.com/genie.phtml?type=process_genie&criteria=exact&auctiongenie=#{CGI::escape item.name}"
|
"https://www.neopets.com/genie.phtml?type=process_genie&criteria=exact&auctiongenie=#{CGI::escape item.name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def trading_closet_hangers_header(owned, count)
|
def trading_closet_hangers_header(owned, count)
|
||||||
|
|
|
@ -159,7 +159,7 @@ function ItemPageBadges({ item, isEmbedded }) {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{item?.ncTradeValueText && (
|
{item?.ncTradeValueText && (
|
||||||
<LinkBadge href="http://www.neopets.com/~owls">
|
<LinkBadge href="https://www.neopets.com/~owls">
|
||||||
OWLS: {item?.ncTradeValueText}
|
OWLS: {item?.ncTradeValueText}
|
||||||
</LinkBadge>
|
</LinkBadge>
|
||||||
)}
|
)}
|
||||||
|
@ -169,7 +169,7 @@ function ItemPageBadges({ item, isEmbedded }) {
|
||||||
{!item?.isNc && !item?.isPb && (
|
{!item?.isNc && !item?.isPb && (
|
||||||
<LinkBadge
|
<LinkBadge
|
||||||
href={
|
href={
|
||||||
"http://www.neopets.com/shops/wizard.phtml?string=" +
|
"https://www.neopets.com/shops/wizard.phtml?string=" +
|
||||||
encodeURIComponent(item?.name)
|
encodeURIComponent(item?.name)
|
||||||
}
|
}
|
||||||
isEmbedded={isEmbedded}
|
isEmbedded={isEmbedded}
|
||||||
|
@ -182,7 +182,7 @@ function ItemPageBadges({ item, isEmbedded }) {
|
||||||
{!item?.isNc && !item?.isPb && (
|
{!item?.isNc && !item?.isPb && (
|
||||||
<LinkBadge
|
<LinkBadge
|
||||||
href={
|
href={
|
||||||
"http://www.neopets.com/portal/supershopwiz.phtml?string=" +
|
"https://www.neopets.com/portal/supershopwiz.phtml?string=" +
|
||||||
encodeURIComponent(item?.name)
|
encodeURIComponent(item?.name)
|
||||||
}
|
}
|
||||||
isEmbedded={isEmbedded}
|
isEmbedded={isEmbedded}
|
||||||
|
@ -195,7 +195,7 @@ function ItemPageBadges({ item, isEmbedded }) {
|
||||||
{!item?.isNc && !item?.isPb && (
|
{!item?.isNc && !item?.isPb && (
|
||||||
<LinkBadge
|
<LinkBadge
|
||||||
href={
|
href={
|
||||||
"http://www.neopets.com/island/tradingpost.phtml?type=browse&criteria=item_exact&search_string=" +
|
"https://www.neopets.com/island/tradingpost.phtml?type=browse&criteria=item_exact&search_string=" +
|
||||||
encodeURIComponent(item?.name)
|
encodeURIComponent(item?.name)
|
||||||
}
|
}
|
||||||
isEmbedded={isEmbedded}
|
isEmbedded={isEmbedded}
|
||||||
|
@ -208,7 +208,7 @@ function ItemPageBadges({ item, isEmbedded }) {
|
||||||
{!item?.isNc && !item?.isPb && (
|
{!item?.isNc && !item?.isPb && (
|
||||||
<LinkBadge
|
<LinkBadge
|
||||||
href={
|
href={
|
||||||
"http://www.neopets.com/genie.phtml?type=process_genie&criteria=exact&auctiongenie=" +
|
"https://www.neopets.com/genie.phtml?type=process_genie&criteria=exact&auctiongenie=" +
|
||||||
encodeURIComponent(item?.name)
|
encodeURIComponent(item?.name)
|
||||||
}
|
}
|
||||||
isEmbedded={isEmbedded}
|
isEmbedded={isEmbedded}
|
||||||
|
|
|
@ -622,7 +622,7 @@ const SWF_URL_PATTERN =
|
||||||
/^https?:\/\/images\.neopets\.com\/cp\/(bio|items)\/swf\/(.+?)_([a-z0-9]+)\.swf$/;
|
/^https?:\/\/images\.neopets\.com\/cp\/(bio|items)\/swf\/(.+?)_([a-z0-9]+)\.swf$/;
|
||||||
|
|
||||||
function convertSwfUrlToPossibleManifestUrls(swfUrl) {
|
function convertSwfUrlToPossibleManifestUrls(swfUrl) {
|
||||||
const match = new URL(swfUrl, "http://images.neopets.com")
|
const match = new URL(swfUrl, "https://images.neopets.com")
|
||||||
.toString()
|
.toString()
|
||||||
.match(SWF_URL_PATTERN);
|
.match(SWF_URL_PATTERN);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
|
@ -636,8 +636,8 @@ function convertSwfUrlToPossibleManifestUrls(swfUrl) {
|
||||||
// TODO: There are a few potential manifest URLs in play! Long-term, we
|
// TODO: There are a few potential manifest URLs in play! Long-term, we
|
||||||
// should get this from modeling data. But these are some good guesses!
|
// should get this from modeling data. But these are some good guesses!
|
||||||
return [
|
return [
|
||||||
`http://images.neopets.com/cp/${type}/data/${folders}/manifest.json`,
|
`https://images.neopets.com/cp/${type}/data/${folders}/manifest.json`,
|
||||||
`http://images.neopets.com/cp/${type}/data/${folders}_${hash}/manifest.json`,
|
`https://images.neopets.com/cp/${type}/data/${folders}_${hash}/manifest.json`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -493,7 +493,7 @@ function getHasAnimationsForMovieAsset({ library, libraryUrl }) {
|
||||||
// Some movie clips require you to tick to the first frame of the movie
|
// Some movie clips require you to tick to the first frame of the movie
|
||||||
// before the children mount onto the stage. If we detect animations
|
// before the children mount onto the stage. If we detect animations
|
||||||
// without doing this, we'll incorrectly say no, because we see no children!
|
// without doing this, we'll incorrectly say no, because we see no children!
|
||||||
// Example: http://images.neopets.com/cp/items/data/000/000/235/235877_6d273e217c/235877.js
|
// Example: https://images.neopets.com/cp/items/data/000/000/235/235877_6d273e217c/235877.js
|
||||||
movieClip.advance();
|
movieClip.advance();
|
||||||
|
|
||||||
const movieClipHasAnimations = hasAnimations(movieClip);
|
const movieClipHasAnimations = hasAnimations(movieClip);
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
module FragmentExpiration
|
|
||||||
include FragmentLocalization
|
|
||||||
|
|
||||||
delegate :expire_fragment, :to => :controller
|
|
||||||
|
|
||||||
def expire_fragment_in_all_locales(key)
|
|
||||||
I18n.usable_locales.each do |locale|
|
|
||||||
localized_key = localize_fragment_key(key, locale)
|
|
||||||
expire_fragment(localized_key)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def expire_key_in_all_locales(key)
|
|
||||||
I18n.usable_locales.each do |locale|
|
|
||||||
localized_key = localize_fragment_key(key, locale)
|
|
||||||
Rails.cache.delete(localized_key)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def controller
|
|
||||||
@controller ||= ActionController::Base.new
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -57,11 +57,11 @@ class Item < ApplicationRecord
|
||||||
}
|
}
|
||||||
scope :is_nc, -> {
|
scope :is_nc, -> {
|
||||||
i = Item.arel_table
|
i = Item.arel_table
|
||||||
where(i[:rarity_index].in(Item::NCRarities).or(i[:is_manually_nc]))
|
where(i[:rarity_index].in(Item::NCRarities).or(i[:is_manually_nc].eq(true)))
|
||||||
}
|
}
|
||||||
scope :is_np, -> {
|
scope :is_np, -> {
|
||||||
i = Item.arel_table
|
i = Item.arel_table
|
||||||
where(i[:rarity_index].in(Item::NCRarities).or(i[:is_manually_nc]).not)
|
where(i[:rarity_index].in(Item::NCRarities).or(i[:is_manually_nc].eq(true)).not)
|
||||||
}
|
}
|
||||||
scope :is_pb, -> {
|
scope :is_pb, -> {
|
||||||
it = Item::Translation.arel_table
|
it = Item::Translation.arel_table
|
||||||
|
@ -631,8 +631,4 @@ class Item < ApplicationRecord
|
||||||
|
|
||||||
items.values
|
items.values
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.build_proxies(ids)
|
|
||||||
Item::ProxyArray.new(ids)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
class Item
|
|
||||||
class Proxy
|
|
||||||
include FragmentLocalization
|
|
||||||
|
|
||||||
attr_reader :id
|
|
||||||
attr_writer :item, :owned, :wanted
|
|
||||||
|
|
||||||
delegate :description, :name, :nc?, :thumbnail_url, :thumbnail, :to_param, to: :item
|
|
||||||
|
|
||||||
def self.model_name
|
|
||||||
Item.model_name
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize(item_or_id)
|
|
||||||
if item_or_id.is_a? Item
|
|
||||||
@item = item_or_id
|
|
||||||
@id = @item.id
|
|
||||||
else
|
|
||||||
@id = item_or_id.to_i
|
|
||||||
end
|
|
||||||
@known_outputs = {method: {}, partial: {}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def as_json(options={})
|
|
||||||
cache_method(:as_json, include_hanger_status: false).tap do |json|
|
|
||||||
json[:owned] = owned?
|
|
||||||
json[:wanted] = wanted?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def owned?
|
|
||||||
@owned
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_partial_path
|
|
||||||
# HACK: could break without warning!
|
|
||||||
Item._to_partial_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def wanted?
|
|
||||||
@wanted
|
|
||||||
end
|
|
||||||
|
|
||||||
def fragment_key(type, name)
|
|
||||||
prefix = type == :partial ? 'views/' : ''
|
|
||||||
base = localize_fragment_key("items/#{@id}##{name}", I18n.locale)
|
|
||||||
prefix + base
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_known_output(type, name, value)
|
|
||||||
@known_outputs[type][name] = value
|
|
||||||
end
|
|
||||||
|
|
||||||
def known_partial_output(name)
|
|
||||||
@known_outputs[:partial][name]
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def cache_method(method_name, *args, &block)
|
|
||||||
# Two layers of cache: a local copy, in case the method is called again,
|
|
||||||
# and then the Rails cache, before we hit the actual method call.
|
|
||||||
@known_outputs[:method][method_name] ||= begin
|
|
||||||
key = fragment_key(:method, method_name)
|
|
||||||
Rails.cache.fetch(key) { item.send(method_name, *args) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def item
|
|
||||||
@item ||= Item.find(@id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,56 +0,0 @@
|
||||||
class Item
|
|
||||||
class ProxyArray < Array
|
|
||||||
# TODO: do we really need to include translations? The search documents
|
|
||||||
# know the proper name for each locale, so proxies can tell their
|
|
||||||
# parent items what their names are and save the query entirely.
|
|
||||||
SCOPES = HashWithIndifferentAccess.new({
|
|
||||||
method: {
|
|
||||||
as_json: Item.includes(:translations),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
def initialize(proxies_or_items_or_ids=[])
|
|
||||||
self.replace(proxies_or_items_or_ids.map { |proxy_or_item_or_id|
|
|
||||||
if proxy_or_item_or_id.is_a?(Proxy)
|
|
||||||
proxy_or_item_or_id
|
|
||||||
else
|
|
||||||
Proxy.new(proxy_or_item_or_id)
|
|
||||||
end
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
def prepare_method(name)
|
|
||||||
prepare(:method, name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def prepare_partial(name)
|
|
||||||
prepare(:partial, name)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def prepare(type, name)
|
|
||||||
item_scope = SCOPES[type][name]
|
|
||||||
raise "unexpected #{type} #{name.inspect}" unless item_scope
|
|
||||||
|
|
||||||
# Try to read all values from the cache in one go, setting the proxy
|
|
||||||
# values as we go along. Delete successfully set proxies, so that
|
|
||||||
# everything left in proxies_by_key in the end is known to be a miss.
|
|
||||||
proxies_by_key = {}
|
|
||||||
self.each do |p|
|
|
||||||
proxies_by_key[p.fragment_key(type, name)] ||= []
|
|
||||||
proxies_by_key[p.fragment_key(type, name)] << p
|
|
||||||
end
|
|
||||||
Rails.cache.read_multi(*proxies_by_key.keys).each { |k, v|
|
|
||||||
proxies_by_key.delete(k).each { |p| p.set_known_output(type, name, v) }
|
|
||||||
}
|
|
||||||
|
|
||||||
missed_proxies = proxies_by_key.values.flatten
|
|
||||||
missed_proxies_by_id = missed_proxies.index_by(&:id)
|
|
||||||
|
|
||||||
item_scope.find(missed_proxies_by_id.keys).each do |item|
|
|
||||||
missed_proxies_by_id[item.id].item = item
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -205,7 +205,7 @@ class NeopetsPage
|
||||||
TYPES = {
|
TYPES = {
|
||||||
'closet' => Type.new(
|
'closet' => Type.new(
|
||||||
get_name: lambda { I18n.translate('neopets_page_import_tasks.names.closet') },
|
get_name: lambda { I18n.translate('neopets_page_import_tasks.names.closet') },
|
||||||
get_url: lambda { |index| "http://www.neopets.com/closet.phtml?per_page=50&page=#{index}" },
|
get_url: lambda { |index| "https://www.neopets.com/closet.phtml?per_page=50&page=#{index}" },
|
||||||
parser: Parser.new(
|
parser: Parser.new(
|
||||||
selectors: {
|
selectors: {
|
||||||
items: "form[action=\"process_closet.phtml\"] tr[bgcolor!=silver][bgcolor!=\"#E4E4E4\"]",
|
items: "form[action=\"process_closet.phtml\"] tr[bgcolor!=silver][bgcolor!=\"#E4E4E4\"]",
|
||||||
|
@ -220,7 +220,7 @@ class NeopetsPage
|
||||||
),
|
),
|
||||||
'safety_deposit' => Type.new(
|
'safety_deposit' => Type.new(
|
||||||
get_name: lambda { I18n.translate('neopets_page_import_tasks.names.safety_deposit') },
|
get_name: lambda { I18n.translate('neopets_page_import_tasks.names.safety_deposit') },
|
||||||
get_url: lambda { |index| "http://www.neopets.com/safetydeposit.phtml?offset=#{(index - 1) * 30}" },
|
get_url: lambda { |index| "https://www.neopets.com/safetydeposit.phtml?offset=#{(index - 1) * 30}" },
|
||||||
parser: Parser.new(
|
parser: Parser.new(
|
||||||
selectors: {
|
selectors: {
|
||||||
items: "#content tr[bgcolor=\"#DFEAF7\"]",
|
items: "#content tr[bgcolor=\"#DFEAF7\"]",
|
||||||
|
@ -242,7 +242,7 @@ class NeopetsPage
|
||||||
),
|
),
|
||||||
'gallery' => Type.new(
|
'gallery' => Type.new(
|
||||||
get_name: lambda { I18n.translate('neopets_page_import_tasks.names.gallery') },
|
get_name: lambda { I18n.translate('neopets_page_import_tasks.names.gallery') },
|
||||||
get_url: lambda { |index| "http://www.neopets.com/gallery/index.phtml?view=all" },
|
get_url: lambda { |index| "https://www.neopets.com/gallery/index.phtml?view=all" },
|
||||||
parser: Parser.new(
|
parser: Parser.new(
|
||||||
selectors: {
|
selectors: {
|
||||||
items: "form[name=gallery_form] td[valign=top]",
|
items: "form[name=gallery_form] td[valign=top]",
|
||||||
|
|
|
@ -5,7 +5,7 @@ class NeopetsUser
|
||||||
include ActiveModel::Conversion
|
include ActiveModel::Conversion
|
||||||
extend ActiveModel::Naming
|
extend ActiveModel::Naming
|
||||||
|
|
||||||
NEOPETS_URL_ORIGIN = ENV['NEOPETS_URL_ORIGIN'] || 'http://www.neopets.com'
|
NEOPETS_URL_ORIGIN = ENV['NEOPETS_URL_ORIGIN'] || 'https://www.neopets.com'
|
||||||
GATEWAY_URL = NEOPETS_URL_ORIGIN + '/amfphp/gateway.php'
|
GATEWAY_URL = NEOPETS_URL_ORIGIN + '/amfphp/gateway.php'
|
||||||
GET_PETS_METHOD = RocketAMF::RemoteGateway.new(GATEWAY_URL).
|
GET_PETS_METHOD = RocketAMF::RemoteGateway.new(GATEWAY_URL).
|
||||||
service('MobileService').action('getPets')
|
service('MobileService').action('getPets')
|
||||||
|
|
|
@ -145,7 +145,7 @@ class PetState < ApplicationRecord
|
||||||
|
|
||||||
def artist_url
|
def artist_url
|
||||||
if artist_neopets_username
|
if artist_neopets_username
|
||||||
"http://www.neopets.com/userlookup.phtml?user=#{artist_neopets_username}"
|
"https://www.neopets.com/userlookup.phtml?user=#{artist_neopets_username}"
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class PetType < ApplicationRecord
|
class PetType < ApplicationRecord
|
||||||
IMAGE_CPN_FORMAT = 'http://pets.neopets.com/cpn/%s/1/1.png';
|
IMAGE_CPN_FORMAT = 'https://pets.neopets.com/cpn/%s/1/1.png';
|
||||||
IMAGE_CP_LOCATION_REGEX = %r{^/cp/(.+?)/[0-9]+/[0-9]+\.png$};
|
IMAGE_CP_LOCATION_REGEX = %r{^/cp/(.+?)/[0-9]+/[0-9]+\.png$};
|
||||||
IMAGE_CPN_ACCEPTABLE_NAME = /^[a-z0-9_]+$/
|
IMAGE_CPN_ACCEPTABLE_NAME = /^[a-z0-9_]+$/
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@
|
||||||
-# TODO: remove me?
|
-# TODO: remove me?
|
||||||
|
|
||||||
- content_for :stylesheets do
|
- content_for :stylesheets do
|
||||||
= stylesheet_link_tag 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/themes/south-street/jquery-ui.css'
|
= stylesheet_link_tag 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/themes/south-street/jquery-ui.css'
|
||||||
|
|
||||||
- content_for :javascripts do
|
- content_for :javascripts do
|
||||||
= include_javascript_libraries :jquery, :jquery_tmpl
|
= include_javascript_libraries :jquery, :jquery_tmpl
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#intro
|
#intro
|
||||||
%p= t '.description'
|
%p= t '.description'
|
||||||
%p= twl '.instructions',
|
%p= twl '.instructions',
|
||||||
:edit_petpage_link_url => 'http://www.neopets.com/edithomepage.phtml'
|
:edit_petpage_link_url => 'https://www.neopets.com/edithomepage.phtml'
|
||||||
|
|
||||||
= form_tag petpage_user_closet_hangers_path(@user), :method => :get, :id => 'petpage-closet-lists' do
|
= form_tag petpage_user_closet_hangers_path(@user), :method => :get, :id => 'petpage-closet-lists' do
|
||||||
= hidden_field_tag 'filter', '1'
|
= hidden_field_tag 'filter', '1'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
- title "Needed items for #{@pet_type.human_name}"
|
- title "Needed items for #{@pet_type.human_name}"
|
||||||
%h2
|
%h2
|
||||||
= image_tag "http://pets.neopets.com/cpn/#{@pet_name}/1/1.png",
|
= image_tag "https://pets.neopets.com/cpn/#{@pet_name}/1/1.png",
|
||||||
:class => 'inline-image'
|
:class => 'inline-image'
|
||||||
%span.pet-name= @pet_name
|
%span.pet-name= @pet_name
|
||||||
can model…
|
can model…
|
||||||
|
@ -11,6 +11,6 @@
|
||||||
= hidden_field_tag 'name', @pet_name
|
= hidden_field_tag 'name', @pet_name
|
||||||
= submit_tag "I'm wearing one now!", :class => 'loud'
|
= submit_tag "I'm wearing one now!", :class => 'loud'
|
||||||
%li
|
%li
|
||||||
= link_to 'What do I own?', 'http://www.neopets.com/closet.phtml',
|
= link_to 'What do I own?', 'https://www.neopets.com/closet.phtml',
|
||||||
:class => 'button', :target => '_blank'
|
:class => 'button', :target => '_blank'
|
||||||
= render @items
|
= render @items
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
- else
|
- else
|
||||||
#{t 'app_name'}: #{t '.title_tagline'}
|
#{t 'app_name'}: #{t '.title_tagline'}
|
||||||
%link{href: image_path('favicon.png'), rel: 'icon'}
|
%link{href: image_path('favicon.png'), rel: 'icon'}
|
||||||
/[if IE]
|
|
||||||
= include_javascript_libraries :html5
|
|
||||||
= yield :stylesheets
|
= yield :stylesheets
|
||||||
= stylesheet_link_tag "application"
|
= stylesheet_link_tag "application"
|
||||||
= yield :meta
|
= yield :meta
|
||||||
|
@ -60,8 +58,8 @@
|
||||||
%noscript= submit_tag 'Go'
|
%noscript= submit_tag 'Go'
|
||||||
|
|
||||||
%ul
|
%ul
|
||||||
%li= link_to t('organization_name'), 'http://openneo.net/'
|
%li= link_to t('organization_name'), 'https://openneo.net/'
|
||||||
%li= link_to t('.footer.blog'), 'http://blog.openneo.net/'
|
%li= link_to t('.footer.blog'), 'https://blog.openneo.net/'
|
||||||
%li= link_to t('.footer.source_code'), 'https://github.com/openneo/impress'
|
%li= link_to t('.footer.source_code'), 'https://github.com/openneo/impress'
|
||||||
%li= link_to t('.footer.terms'), terms_path
|
%li= link_to t('.footer.terms'), terms_path
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
- content_for :before_flashes do
|
- content_for :before_flashes do
|
||||||
%h1
|
%h1
|
||||||
= link_to items_path do
|
= link_to items_path do
|
||||||
= image_tag 'http://images.neopets.com/items/mall_floatingneggfaerie.gif'
|
= image_tag 'https://images.neopets.com/items/mall_floatingneggfaerie.gif'
|
||||||
%span= t 'infinite_closet'
|
%span= t 'infinite_closet'
|
||||||
- content_for :content do
|
- content_for :content do
|
||||||
= form_tag items_path, :method => :get do
|
= form_tag items_path, :method => :get do
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
|
|
||||||
%li
|
%li
|
||||||
= link_to bulk_pets_path do
|
= link_to bulk_pets_path do
|
||||||
= image_tag 'http://images.neopets.com/items/mall_ac_garland_spotlight.gif'
|
= image_tag 'https://images.neopets.com/items/mall_ac_garland_spotlight.gif'
|
||||||
%h3= link_to t('modeling_hub'), bulk_pets_path
|
%h3= link_to t('modeling_hub'), bulk_pets_path
|
||||||
%div
|
%div
|
||||||
%h4= t '.modeling_hub.tagline'
|
%h4= t '.modeling_hub.tagline'
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
|
|
||||||
%script#bulk-pets-submission-template{:type => 'text/x-jquery/tmpl'}
|
%script#bulk-pets-submission-template{:type => 'text/x-jquery/tmpl'}
|
||||||
%li.waiting
|
%li.waiting
|
||||||
%img{:src => 'http://pets.neopets.com/cpn/${pet_name}/1/1.png'}
|
%img{:src => 'https://pets.neopets.com/cpn/${pet_name}/1/1.png'}
|
||||||
%span.name ${pet_name}
|
%span.name ${pet_name}
|
||||||
%span.waiting-message= t '.bulk_pets.waiting'
|
%span.waiting-message= t '.bulk_pets.waiting'
|
||||||
%span.loading-message= t '.bulk_pets.loading'
|
%span.loading-message= t '.bulk_pets.loading'
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
!!! XML
|
!!! XML
|
||||||
%urlset{:xmlns => "http://www.sitemaps.org/schemas/sitemap/0.9"}
|
%urlset{:xmlns => "https://www.sitemaps.org/schemas/sitemap/0.9"}
|
||||||
- for item in @items
|
- for item in @items
|
||||||
%url
|
%url
|
||||||
%loc http://#{request.host_with_port}#{url_for(item)}
|
%loc https://#{request.host_with_port}#{url_for(item)}
|
||||||
%changefreq monthly
|
%changefreq monthly
|
||||||
%priority 0.5
|
%priority 0.5
|
||||||
|
|
||||||
|
|
|
@ -49,11 +49,11 @@
|
||||||
Downloading currently only works for modern browsers that support the new
|
Downloading currently only works for modern browsers that support the new
|
||||||
canvas feature. It is, however, supported in the latest versions of,
|
canvas feature. It is, however, supported in the latest versions of,
|
||||||
|
|
||||||
* [Google Chrome](http://www.google.com/chrome)
|
* [Google Chrome](https://www.google.com/chrome)
|
||||||
* [Mozilla Firefox](http://www.firefox.com/)
|
* [Mozilla Firefox](https://www.firefox.com/)
|
||||||
* [Opera](http://www.opera.com/)
|
* [Opera](https://www.opera.com/)
|
||||||
* [Safari](http://www.apple.com/safari/)
|
* [Safari](https://www.apple.com/safari/)
|
||||||
* [Internet Explorer](http://www.microsoft.com/ie)
|
* [Internet Explorer](https://www.microsoft.com/ie)
|
||||||
|
|
||||||
However, Internet Explorer currently is having trouble running Dress to
|
However, Internet Explorer currently is having trouble running Dress to
|
||||||
Impress in general, so is not recommended.
|
Impress in general, so is not recommended.
|
||||||
|
|
|
@ -5,7 +5,7 @@ require "fileutils"
|
||||||
APP_ROOT = File.expand_path("..", __dir__)
|
APP_ROOT = File.expand_path("..", __dir__)
|
||||||
|
|
||||||
def system!(*args)
|
def system!(*args)
|
||||||
system(*args) || abort("\n== Command #{args} failed ==")
|
system(*args, exception: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
FileUtils.chdir APP_ROOT do
|
FileUtils.chdir APP_ROOT do
|
||||||
|
|
|
@ -9,19 +9,21 @@ Bundler.require(*Rails.groups)
|
||||||
module OpenneoImpressItems
|
module OpenneoImpressItems
|
||||||
class Application < Rails::Application
|
class Application < Rails::Application
|
||||||
# Initialize configuration defaults for originally generated Rails version.
|
# Initialize configuration defaults for originally generated Rails version.
|
||||||
config.load_defaults 7.0
|
config.load_defaults 7.1
|
||||||
|
|
||||||
# Settings in config/environments/* take precedence over those specified here.
|
# Please, add to the `ignore` list any other `lib` subdirectories that do
|
||||||
# Application configuration should go into files in config/initializers
|
# not contain `.rb` files, or that should not be reloaded or eager loaded.
|
||||||
# -- all .rb files in that directory are automatically loaded.
|
# Common ones are `templates`, `generators`, or `middleware`, for example.
|
||||||
|
config.autoload_lib(ignore: %w(assets tasks))
|
||||||
|
|
||||||
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
# Configuration for the application, engines, and railties goes here.
|
||||||
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
#
|
||||||
# config.time_zone = 'Central Time (US & Canada)'
|
# These settings can be overridden in specific environments using the files
|
||||||
|
# in config/environments, which are processed later.
|
||||||
|
#
|
||||||
|
# config.time_zone = "Central Time (US & Canada)"
|
||||||
|
# config.eager_load_paths << Rails.root.join("extras")
|
||||||
|
|
||||||
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
|
||||||
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
|
||||||
# config.i18n.default_locale = :de
|
|
||||||
config.i18n.fallbacks = true
|
config.i18n.fallbacks = true
|
||||||
|
|
||||||
Mime::Type.register "image/gif", :gif
|
Mime::Type.register "image/gif", :gif
|
||||||
|
|
|
@ -3,10 +3,10 @@ require "active_support/core_ext/integer/time"
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
# Settings specified here will take precedence over those in config/application.rb.
|
# Settings specified here will take precedence over those in config/application.rb.
|
||||||
|
|
||||||
# In the development environment your application's code is reloaded on
|
# In the development environment your application's code is reloaded any time
|
||||||
# every request. This slows down response time but is perfect for development
|
# it changes. This slows down response time but is perfect for development
|
||||||
# since you don't have to restart the web server when you make code changes.
|
# since you don't have to restart the web server when you make code changes.
|
||||||
config.cache_classes = false
|
config.enable_reloading = true
|
||||||
|
|
||||||
# Do not eager load code on boot.
|
# Do not eager load code on boot.
|
||||||
config.eager_load = false
|
config.eager_load = false
|
||||||
|
@ -25,7 +25,7 @@ Rails.application.configure do
|
||||||
|
|
||||||
config.cache_store = :memory_store
|
config.cache_store = :memory_store
|
||||||
config.public_file_server.headers = {
|
config.public_file_server.headers = {
|
||||||
'Cache-Control' => "public, max-age=#{2.days.to_i}"
|
"Cache-Control" => "public, max-age=#{2.days.to_i}"
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
config.action_controller.perform_caching = false
|
config.action_controller.perform_caching = false
|
||||||
|
@ -33,16 +33,22 @@ Rails.application.configure do
|
||||||
config.cache_store = :null_store
|
config.cache_store = :null_store
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Store uploaded files on the local file system (see config/storage.yml for options).
|
||||||
|
config.active_storage.service = :local
|
||||||
|
|
||||||
# Don't care if the mailer can't send.
|
# Don't care if the mailer can't send.
|
||||||
config.action_mailer.raise_delivery_errors = false
|
config.action_mailer.raise_delivery_errors = false
|
||||||
config.action_mailer.default_url_options = {host: "localhost", port: 3000}
|
config.action_mailer.default_url_options = {host: "localhost", port: 3000}
|
||||||
config.action_mailer.delivery_method = :letter_opener
|
config.action_mailer.delivery_method = :letter_opener
|
||||||
config.action_mailer.perform_caching = false
|
config.action_mailer.perform_caching = false
|
||||||
|
|
||||||
# Print deprecation notices to the Rails logger.
|
# Raise exceptions for disallowed deprecations.
|
||||||
config.active_support.deprecation = :log
|
config.active_support.disallowed_deprecation = :raise
|
||||||
|
|
||||||
# Raise an error on page load if there are pending migrations
|
# Tell Active Support which deprecation messages to disallow.
|
||||||
|
config.active_support.disallowed_deprecation_warnings = []
|
||||||
|
|
||||||
|
# Raise an error on page load if there are pending migrations.
|
||||||
config.active_record.migration_error = :page_load
|
config.active_record.migration_error = :page_load
|
||||||
|
|
||||||
# Debug mode disables concatenation and preprocessing of assets.
|
# Debug mode disables concatenation and preprocessing of assets.
|
||||||
|
@ -53,11 +59,26 @@ Rails.application.configure do
|
||||||
# Highlight code that triggered database queries in logs.
|
# Highlight code that triggered database queries in logs.
|
||||||
config.active_record.verbose_query_logs = true
|
config.active_record.verbose_query_logs = true
|
||||||
|
|
||||||
|
# Highlight code that enqueued background job in logs.
|
||||||
|
config.active_job.verbose_enqueue_logs = true
|
||||||
|
|
||||||
# Suppress logger output for asset requests.
|
# Suppress logger output for asset requests.
|
||||||
config.assets.quiet = true
|
config.assets.quiet = true
|
||||||
|
|
||||||
config.react.variant = :development
|
config.react.variant = :development
|
||||||
|
|
||||||
|
# Raises error for missing translations.
|
||||||
|
# config.i18n.raise_on_missing_translations = true
|
||||||
|
|
||||||
|
# Annotate rendered view with file names.
|
||||||
|
# config.action_view.annotate_rendered_view_with_filenames = true
|
||||||
|
|
||||||
|
# Uncomment if you wish to allow Action Cable access from any origin.
|
||||||
|
# config.action_cable.disable_request_forgery_protection = true
|
||||||
|
|
||||||
|
# Raise error when a before_action's only/except options reference missing actions
|
||||||
|
config.action_controller.raise_on_missing_callback_actions = true
|
||||||
|
|
||||||
# Don't use the assets precompiled for production; recompile live instead.
|
# Don't use the assets precompiled for production; recompile live instead.
|
||||||
# HACK: We do this by just telling it that dev assets belong in a special
|
# HACK: We do this by just telling it that dev assets belong in a special
|
||||||
# folder, so if you run precompile in development it'll look there instead,
|
# folder, so if you run precompile in development it'll look there instead,
|
||||||
|
@ -82,8 +103,3 @@ Rails.application.configure do
|
||||||
# Allow connections on Vagrant's private network.
|
# Allow connections on Vagrant's private network.
|
||||||
config.web_console.permissions = '10.0.2.2'
|
config.web_console.permissions = '10.0.2.2'
|
||||||
end
|
end
|
||||||
|
|
||||||
LocalImpressHost = 'betanewimpress.openneo.net'
|
|
||||||
|
|
||||||
RemoteImpressHost = 'beta.impress.openneo.net'
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ Rails.application.configure do
|
||||||
# Settings specified here will take precedence over those in config/application.rb.
|
# Settings specified here will take precedence over those in config/application.rb.
|
||||||
|
|
||||||
# Code is not reloaded between requests.
|
# Code is not reloaded between requests.
|
||||||
config.cache_classes = true
|
config.enable_reloading = false
|
||||||
|
|
||||||
# Eager load code on boot. This eager loads most of Rails and
|
# Eager load code on boot. This eager loads most of Rails and
|
||||||
# your application in memory, allowing both threaded web servers
|
# your application in memory, allowing both threaded web servers
|
||||||
|
@ -16,68 +16,69 @@ Rails.application.configure do
|
||||||
config.consider_all_requests_local = false
|
config.consider_all_requests_local = false
|
||||||
config.action_controller.perform_caching = true
|
config.action_controller.perform_caching = true
|
||||||
|
|
||||||
# Specifies the header that your server uses for sending files
|
# Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
|
||||||
config.action_dispatch.x_sendfile_header = "X-Sendfile"
|
# key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
|
||||||
|
# config.require_master_key = true
|
||||||
|
|
||||||
# For nginx:
|
# Enable static file serving from the `/public` folder (turn off if using NGINX/Apache for it).
|
||||||
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
|
config.public_file_server.enabled = false
|
||||||
|
|
||||||
# If you have no front-end server that supports something like X-Sendfile,
|
# Compress CSS using a preprocessor.
|
||||||
# just comment this out and Rails will serve the files
|
# config.assets.css_compressor = :sass
|
||||||
|
|
||||||
# See everything in the log (default is :info)
|
# Compress JS using a preprocessor.
|
||||||
# config.log_level = :debug
|
config.assets.js_compressor = :terser
|
||||||
|
|
||||||
# Use a different logger for distributed setups
|
# Do not fallback to assets pipeline if a precompiled asset is missed.
|
||||||
# config.logger = SyslogLogger.new
|
config.assets.compile = false
|
||||||
|
|
||||||
# Use a different cache store in production
|
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
|
||||||
# config.cache_store = :mem_cache_store, { namespace: "openneo-impress-rails" }
|
# config.asset_host = "http://assets.example.com"
|
||||||
|
|
||||||
# Disable Rails's static asset server
|
# Specifies the header that your server uses for sending files.
|
||||||
# In production, Apache or nginx will already do this
|
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
|
||||||
# config.serve_static_assets = true
|
# config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX
|
||||||
|
|
||||||
# Enable serving of images, stylesheets, and javascripts from an asset server
|
# Store uploaded files on the local file system (see config/storage.yml for options).
|
||||||
# config.action_controller.asset_host = "http://assets.example.com"
|
config.active_storage.service = :local
|
||||||
|
|
||||||
# Disable delivery errors, bad email addresses will be ignored
|
# Mount Action Cable outside main process or domain.
|
||||||
# config.action_mailer.raise_delivery_errors = false
|
# config.action_cable.mount_path = nil
|
||||||
|
# config.action_cable.url = "wss://example.com/cable"
|
||||||
|
# config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ]
|
||||||
|
|
||||||
# Enable threaded mode
|
# Assume all access to the app is happening through a SSL-terminating reverse proxy.
|
||||||
# config.threadsafe!
|
# Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
|
||||||
|
config.assume_ssl = true
|
||||||
|
|
||||||
# Disable serving static files from the `/public` folder by default since
|
# Disable serving static files from the `/public` folder by default since
|
||||||
# Apache or NGINX already handles this.
|
# Apache or NGINX already handles this.
|
||||||
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
|
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
|
||||||
|
|
||||||
# Compress JavaScripts and CSS.
|
|
||||||
config.assets.js_compressor = :terser
|
|
||||||
|
|
||||||
# Don't fallback to assets pipeline if a precompiled asset is missed
|
# Don't fallback to assets pipeline if a precompiled asset is missed
|
||||||
config.assets.compile = false
|
config.assets.compile = false
|
||||||
|
|
||||||
# Generate digests for assets URLs
|
|
||||||
config.assets.digest = true
|
|
||||||
|
|
||||||
# Defaults to Rails.root.join("public/assets")
|
|
||||||
# config.assets.manifest = YOUR_PATH
|
|
||||||
|
|
||||||
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
|
|
||||||
# config.assets.precompile += %w( search.js )
|
|
||||||
|
|
||||||
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
||||||
# config.force_ssl = true
|
config.force_ssl = true
|
||||||
|
|
||||||
# Include generic and useful information about system operation, but avoid logging too much
|
# Log to STDOUT by default
|
||||||
# information to avoid inadvertent exposure of personally identifiable information (PII).
|
config.logger = ActiveSupport::Logger.new(STDOUT)
|
||||||
config.log_level = :info
|
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
|
||||||
|
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }
|
||||||
|
|
||||||
# Prepend all log lines with the following tags.
|
# Prepend all log lines with the following tags.
|
||||||
config.log_tags = [ :request_id ]
|
config.log_tags = [ :request_id ]
|
||||||
|
|
||||||
config.react.variant = :production
|
config.react.variant = :production
|
||||||
|
|
||||||
|
# Info include generic and useful information about system operation, but avoids logging too much
|
||||||
|
# information to avoid inadvertent exposure of personally identifiable information (PII). If you
|
||||||
|
# want to log everything, set the level to "debug".
|
||||||
|
config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
|
||||||
|
|
||||||
|
# Use a different cache store in production.
|
||||||
|
# config.cache_store = :mem_cache_store
|
||||||
|
|
||||||
config.action_mailer.default_url_options = {host: "impress.openneo.net"}
|
config.action_mailer.default_url_options = {host: "impress.openneo.net"}
|
||||||
|
|
||||||
config.action_mailer.delivery_method = :smtp
|
config.action_mailer.delivery_method = :smtp
|
||||||
|
@ -94,26 +95,29 @@ Rails.application.configure do
|
||||||
config.action_mailer.perform_deliveries = true
|
config.action_mailer.perform_deliveries = true
|
||||||
config.action_mailer.perform_caching = false
|
config.action_mailer.perform_caching = false
|
||||||
|
|
||||||
|
# Use a real queuing backend for Active Job (and separate queues per environment).
|
||||||
|
# config.active_job.queue_adapter = :resque
|
||||||
|
# config.active_job.queue_name_prefix = "openneo_impress_items_production"
|
||||||
|
|
||||||
|
# Ignore bad email addresses and do not raise email delivery errors.
|
||||||
|
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
|
||||||
|
# config.action_mailer.raise_delivery_errors = false
|
||||||
|
|
||||||
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
||||||
# the I18n.default_locale when a translation cannot be found).
|
# the I18n.default_locale when a translation cannot be found).
|
||||||
config.i18n.fallbacks = true
|
config.i18n.fallbacks = true
|
||||||
|
|
||||||
# Send deprecation notices to registered listeners.
|
# Don't log any deprecations.
|
||||||
config.active_support.report_deprecations = false
|
config.active_support.report_deprecations = false
|
||||||
|
|
||||||
# Use default logging formatter so that PID and timestamp are not suppressed.
|
|
||||||
config.log_formatter = ::Logger::Formatter.new
|
|
||||||
|
|
||||||
if ENV["RAILS_LOG_TO_STDOUT"].present?
|
|
||||||
logger = ActiveSupport::Logger.new(STDOUT)
|
|
||||||
logger.formatter = config.log_formatter
|
|
||||||
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Do not dump schema after migrations.
|
# Do not dump schema after migrations.
|
||||||
config.active_record.dump_schema_after_migration = false
|
config.active_record.dump_schema_after_migration = false
|
||||||
|
|
||||||
|
# Enable DNS rebinding protection and other `Host` header attacks.
|
||||||
|
# config.hosts = [
|
||||||
|
# "example.com", # Allow requests from example.com
|
||||||
|
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
|
||||||
|
# ]
|
||||||
|
# Skip DNS rebinding protection for the default health check endpoint.
|
||||||
|
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
|
||||||
end
|
end
|
||||||
|
|
||||||
LocalImpressHost = 'newimpress.openneo.net'
|
|
||||||
|
|
||||||
RemoteImpressHost = 'impress.openneo.net'
|
|
||||||
|
|
|
@ -8,12 +8,13 @@ require "active_support/core_ext/integer/time"
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
# Settings specified here will take precedence over those in config/application.rb.
|
# Settings specified here will take precedence over those in config/application.rb.
|
||||||
|
|
||||||
# Turn false under Spring and add config.action_view.cache_template_loading = true.
|
# While tests run files are not watched, reloading is not necessary.
|
||||||
config.cache_classes = true
|
config.enable_reloading = false
|
||||||
|
|
||||||
# Eager loading loads your whole application. When running a single test locally,
|
# Eager loading loads your entire application. When running a single test locally,
|
||||||
# this probably isn't necessary. It's a good idea to do in a continuous integration
|
# this is usually not necessary, and can slow down your test suite. However, it's
|
||||||
# system, or in some way before deploying your code.
|
# recommended that you enable it in continuous integration systems to ensure eager
|
||||||
|
# loading is working properly before deploying your code.
|
||||||
config.eager_load = ENV["CI"].present?
|
config.eager_load = ENV["CI"].present?
|
||||||
|
|
||||||
# Configure public file server for tests with Cache-Control for performance.
|
# Configure public file server for tests with Cache-Control for performance.
|
||||||
|
@ -28,7 +29,7 @@ Rails.application.configure do
|
||||||
config.cache_store = :null_store
|
config.cache_store = :null_store
|
||||||
|
|
||||||
# Raise exceptions instead of rendering exception templates.
|
# Raise exceptions instead of rendering exception templates.
|
||||||
config.action_dispatch.show_exceptions = false
|
config.action_dispatch.show_exceptions = :rescuable
|
||||||
|
|
||||||
# Disable request forgery protection in test environment.
|
# Disable request forgery protection in test environment.
|
||||||
config.action_controller.allow_forgery_protection = false
|
config.action_controller.allow_forgery_protection = false
|
||||||
|
@ -57,4 +58,7 @@ Rails.application.configure do
|
||||||
|
|
||||||
# Annotate rendered view with file names.
|
# Annotate rendered view with file names.
|
||||||
# config.action_view.annotate_rendered_view_with_filenames = true
|
# config.action_view.annotate_rendered_view_with_filenames = true
|
||||||
|
|
||||||
|
# Raise error when a before_action's only/except options reference missing actions
|
||||||
|
config.action_controller.raise_on_missing_callback_actions = true
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
# # policy.report_uri "/csp-violation-report-endpoint"
|
# # policy.report_uri "/csp-violation-report-endpoint"
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# # Generate session nonces for permitted importmap and inline scripts
|
# # Generate session nonces for permitted importmap, inline scripts, and inline styles.
|
||||||
# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
|
# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
|
||||||
# config.content_security_policy_nonce_directives = %w(script-src)
|
# config.content_security_policy_nonce_directives = %w(script-src style-src)
|
||||||
#
|
#
|
||||||
# # Report violations without enforcing the policy.
|
# # Report violations without enforcing the policy.
|
||||||
# # config.content_security_policy_report_only = true
|
# # config.content_security_policy_report_only = true
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Be sure to restart your server when you modify this file.
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
# Configure parameters to be filtered from the log file. Use this to limit dissemination of
|
# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
|
||||||
# sensitive information. See the ActiveSupport::ParameterFilter documentation for supported
|
# Use this to limit dissemination of sensitive information.
|
||||||
# notations and behaviors.
|
# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
|
||||||
Rails.application.config.filter_parameters += [
|
Rails.application.config.filter_parameters += [
|
||||||
:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
|
:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
|
||||||
]
|
]
|
||||||
|
|
|
@ -14,3 +14,8 @@
|
||||||
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||||
# inflect.acronym "RESTful"
|
# inflect.acronym "RESTful"
|
||||||
# end
|
# end
|
||||||
|
|
||||||
|
# Teach Zeitwerk that `RocketAMF` is what to expect in `lib/rocketamf`.
|
||||||
|
ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||||
|
inflect.acronym "RocketAMF"
|
||||||
|
end
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
if Rails.env.production?
|
|
||||||
Rails.configuration.neopia_host = 'neopia.openneo.net'
|
|
||||||
else
|
|
||||||
Rails.configuration.neopia_host = 'neopia.dev.openneo.net'
|
|
||||||
end
|
|
|
@ -1,11 +1,13 @@
|
||||||
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
# Define an application-wide HTTP permissions policy. For further
|
# Define an application-wide HTTP permissions policy. For further
|
||||||
# information see https://developers.google.com/web/updates/2018/06/feature-policy
|
# information see: https://developers.google.com/web/updates/2018/06/feature-policy
|
||||||
#
|
|
||||||
# Rails.application.config.permissions_policy do |f|
|
# Rails.application.config.permissions_policy do |policy|
|
||||||
# f.camera :none
|
# policy.camera :none
|
||||||
# f.gyroscope :none
|
# policy.gyroscope :none
|
||||||
# f.microphone :none
|
# policy.microphone :none
|
||||||
# f.usb :none
|
# policy.usb :none
|
||||||
# f.fullscreen :self
|
# policy.fullscreen :self
|
||||||
# f.payment :self, "https://secure.example.com"
|
# policy.payment :self, "https://secure.example.com"
|
||||||
# end
|
# end
|
||||||
|
|
|
@ -9,4 +9,11 @@
|
||||||
|
|
||||||
# Make sure your secret_key_base is kept private
|
# Make sure your secret_key_base is kept private
|
||||||
# if you're sharing your code publicly.
|
# if you're sharing your code publicly.
|
||||||
OpenneoImpressItems::Application.config.secret_key_base = ENV.fetch('SECRET_TOKEN')
|
if Rails.env.development?
|
||||||
|
# In development, we use a hardcoded secret key, because it doesn't actually
|
||||||
|
# need to be secret!
|
||||||
|
OpenneoImpressItems::Application.config.secret_key_base = "7584841652f89044a8b5a428efa6dfac2461449eb24741a33668cd642130d79f93b0347766ebf4a4d7d5033a263c36431594ad56b5735a7325c8cdda991219c2"
|
||||||
|
else
|
||||||
|
# In general, we use the SECRET_TOKEN provided as an environment variable!
|
||||||
|
OpenneoImpressItems::Application.config.secret_key_base = ENV.fetch('SECRET_TOKEN')
|
||||||
|
end
|
||||||
|
|
29
deploy/files/impress.service
Normal file
29
deploy/files/impress.service
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Dress to Impress webapp
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=impress
|
||||||
|
Restart=always
|
||||||
|
WorkingDirectory=/srv/impress/current
|
||||||
|
ExecStart=/opt/ruby-3.1.4/bin/bundle exec puma --port=3000
|
||||||
|
Environment="RAILS_ENV=production"
|
||||||
|
; Set EXECJS_RUNTIME to save us from needing to install Node
|
||||||
|
Environment="EXECJS_RUNTIME=Disabled"
|
||||||
|
EnvironmentFile=/srv/impress/shared/production.env
|
||||||
|
|
||||||
|
; Some security directives, adapted from Akkoma's service file, they seem like sensible defaults!
|
||||||
|
; Use private /tmp and /var/tmp folders inside a new file system namespace, which are discarded after the process stops.
|
||||||
|
PrivateTmp=true
|
||||||
|
; The /home, /root, and /run/user folders can not be accessed by this service anymore. If your Akkoma user has its home folder in one of the restricted places, or use one of these folders as its working directory, you have to set this to false.
|
||||||
|
ProtectHome=true
|
||||||
|
; Mount /usr, /boot, and /etc as read-only for processes invoked by this service.
|
||||||
|
ProtectSystem=full
|
||||||
|
; Sets up a new /dev mount for the process and only adds API pseudo devices like /dev/null, /dev/zero or /dev/random but not physical devices.
|
||||||
|
PrivateDevices=true
|
||||||
|
; Ensures that the service process and all its children can never gain new privileges through execve().
|
||||||
|
NoNewPrivileges=true
|
||||||
|
; Drops the sysadmin capability from the daemon.
|
||||||
|
CapabilityBoundingSet=~CAP_SYS_ADMIN
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
|
@ -1,2 +1,2 @@
|
||||||
source 'http://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
gem 'puma', '~> 6.3'
|
gem 'puma', '~> 6.3'
|
|
@ -1,11 +1,12 @@
|
||||||
GEM
|
GEM
|
||||||
remote: http://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
nio4r (2.5.9)
|
nio4r (2.5.9)
|
||||||
puma (6.3.0)
|
puma (6.3.0)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
|
x86_64-darwin-21
|
||||||
x86_64-linux
|
x86_64-linux
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
|
|
44
deploy/files/sites-available/impress.conf
Normal file
44
deploy/files/sites-available/impress.conf
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
server {
|
||||||
|
server_name {{ impress_hostname }};
|
||||||
|
listen 80;
|
||||||
|
if ($host = {{ impress_hostname }}) {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
server_name {{ impress_hostname }};
|
||||||
|
listen 443 ssl;
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{{ impress_hostname }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{{ impress_hostname }}/privkey.pem;
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||||
|
ssl_session_cache shared:SSL:10m; # https://superuser.com/q/1484466/14127
|
||||||
|
|
||||||
|
root /srv/impress/current/public;
|
||||||
|
|
||||||
|
# Serve assets using their precompressed *.gz versions.
|
||||||
|
# The filenames contain content hashes, so they should be safe to
|
||||||
|
# cache forever.
|
||||||
|
# https://stackoverflow.com/a/6952804/107415
|
||||||
|
location ~ ^/assets/ {
|
||||||
|
gzip_static on;
|
||||||
|
expires max;
|
||||||
|
add_header Cache-Control public;
|
||||||
|
add_header Last-Modified "";
|
||||||
|
add_header ETag "";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Try serving static files first. If not found, fall back to the app.
|
||||||
|
try_files $uri/index.html $uri @app;
|
||||||
|
|
||||||
|
location @app {
|
||||||
|
proxy_pass http://127.0.0.1:3000;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
proxy_set_header X-Forwarded-Server $host;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_redirect off;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
# There is currently only one impress box in our Ansible inventory!
|
# There is currently only one impress box in our Ansible inventory!
|
||||||
[webserver]
|
[webserver]
|
||||||
beta.impress.openneo.net
|
impress.openneo.net
|
||||||
|
|
111
deploy/setup.yml
111
deploy/setup.yml
|
@ -5,7 +5,7 @@
|
||||||
become_user: root
|
become_user: root
|
||||||
vars:
|
vars:
|
||||||
email_address: "emi@matchu.dev" # TODO: Extract this to personal config?
|
email_address: "emi@matchu.dev" # TODO: Extract this to personal config?
|
||||||
impress_hostname: beta.impress.openneo.net
|
impress_hostname: impress.openneo.net
|
||||||
tasks:
|
tasks:
|
||||||
- name: Create SSH folder for logged-in user
|
- name: Create SSH folder for logged-in user
|
||||||
become: no
|
become: no
|
||||||
|
@ -164,7 +164,9 @@
|
||||||
|
|
||||||
- name: Install system dependencies for impress's Ruby gems
|
- name: Install system dependencies for impress's Ruby gems
|
||||||
apt:
|
apt:
|
||||||
name: libmysqlclient-dev
|
name:
|
||||||
|
- libmysqlclient-dev
|
||||||
|
- libyaml-dev
|
||||||
|
|
||||||
- name: Create the app folder
|
- name: Create the app folder
|
||||||
file:
|
file:
|
||||||
|
@ -255,37 +257,8 @@
|
||||||
|
|
||||||
- name: Create service file for impress
|
- name: Create service file for impress
|
||||||
copy:
|
copy:
|
||||||
|
src: files/impress.service
|
||||||
dest: /etc/systemd/system/impress.service
|
dest: /etc/systemd/system/impress.service
|
||||||
content: |
|
|
||||||
[Unit]
|
|
||||||
Description=Dress to Impress webapp
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
User=impress
|
|
||||||
Restart=always
|
|
||||||
WorkingDirectory=/srv/impress/current
|
|
||||||
ExecStart=/opt/ruby-3.1.4/bin/bundle exec puma --port=3000
|
|
||||||
Environment="RAILS_ENV=production"
|
|
||||||
; Set EXECJS_RUNTIME to save us from needing to install Node
|
|
||||||
Environment="EXECJS_RUNTIME=Disabled"
|
|
||||||
EnvironmentFile=/srv/impress/shared/production.env
|
|
||||||
|
|
||||||
; Some security directives, adapted from Akkoma's service file, they seem like sensible defaults!
|
|
||||||
; Use private /tmp and /var/tmp folders inside a new file system namespace, which are discarded after the process stops.
|
|
||||||
PrivateTmp=true
|
|
||||||
; The /home, /root, and /run/user folders can not be accessed by this service anymore. If your Akkoma user has its home folder in one of the restricted places, or use one of these folders as its working directory, you have to set this to false.
|
|
||||||
ProtectHome=true
|
|
||||||
; Mount /usr, /boot, and /etc as read-only for processes invoked by this service.
|
|
||||||
ProtectSystem=full
|
|
||||||
; Sets up a new /dev mount for the process and only adds API pseudo devices like /dev/null, /dev/zero or /dev/random but not physical devices.
|
|
||||||
PrivateDevices=true
|
|
||||||
; Ensures that the service process and all its children can never gain new privileges through execve().
|
|
||||||
NoNewPrivileges=true
|
|
||||||
; Drops the sysadmin capability from the daemon.
|
|
||||||
CapabilityBoundingSet=~CAP_SYS_ADMIN
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
notify:
|
notify:
|
||||||
- Reload systemctl
|
- Reload systemctl
|
||||||
- Restart impress
|
- Restart impress
|
||||||
|
@ -310,79 +283,11 @@
|
||||||
classic: yes
|
classic: yes
|
||||||
|
|
||||||
- name: Set up certbot
|
- name: Set up certbot
|
||||||
command: "certbot certonly --nginx -n --agree-tos --email {{ email_address }} --domains beta.impress.openneo.net"
|
command: "certbot certonly --nginx -n --agree-tos --email {{ email_address }} --domains {{ impress_hostname }}"
|
||||||
|
|
||||||
# TODO: Remove the duplication once we've fully switched over hosts!
|
|
||||||
# NOTE: I migrated over the certs manually, we'll want to have certbot
|
|
||||||
# replace them once it's recognized as impress.openneo.net!
|
|
||||||
- name: Add impress config file to nginx
|
- name: Add impress config file to nginx
|
||||||
copy:
|
template:
|
||||||
content: |
|
src: files/sites-available/impress.conf
|
||||||
server {
|
|
||||||
server_name impress.openneo.net;
|
|
||||||
listen 80;
|
|
||||||
if ($host = impress.openneo.net) {
|
|
||||||
return 301 https://$host$request_uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
server_name impress.openneo.net;
|
|
||||||
listen 443 ssl;
|
|
||||||
ssl_certificate /etc/letsencrypt/live/impress.openneo.net/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/impress.openneo.net/privkey.pem;
|
|
||||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
|
||||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
|
||||||
ssl_session_cache shared:SSL:10m; # https://superuser.com/q/1484466/14127
|
|
||||||
|
|
||||||
root /srv/impress/current/public;
|
|
||||||
|
|
||||||
# Try serving static files first. If not found, fall back to the app.
|
|
||||||
try_files $uri/index.html $uri @app;
|
|
||||||
|
|
||||||
location @app {
|
|
||||||
proxy_pass http://127.0.0.1:3000;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_set_header X-Forwarded-Server $host;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
server_name {{ impress_hostname }};
|
|
||||||
listen 80;
|
|
||||||
if ($host = {{ impress_hostname }}) {
|
|
||||||
return 301 https://$host$request_uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
server_name {{ impress_hostname }};
|
|
||||||
listen 443 ssl;
|
|
||||||
ssl_certificate /etc/letsencrypt/live/{{ impress_hostname }}/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/{{ impress_hostname }}/privkey.pem;
|
|
||||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
|
||||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
|
||||||
ssl_session_cache shared:SSL:10m; # https://superuser.com/q/1484466/14127
|
|
||||||
|
|
||||||
root /srv/impress/current/public;
|
|
||||||
|
|
||||||
# Try serving static files first. If not found, fall back to the app.
|
|
||||||
try_files $uri/index.html $uri @app;
|
|
||||||
|
|
||||||
location @app {
|
|
||||||
proxy_pass http://127.0.0.1:3000;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_set_header X-Forwarded-Server $host;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dest: /etc/nginx/sites-available/impress.conf
|
dest: /etc/nginx/sites-available/impress.conf
|
||||||
notify:
|
notify:
|
||||||
- Restart nginx
|
- Restart nginx
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
Use this README file to introduce your application and point to useful places in the API for learning more.
|
|
||||||
Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
|
|
|
@ -50,7 +50,7 @@ namespace :pet_types do
|
||||||
desc "Download the Rainbow Pool data for the given locale"
|
desc "Download the Rainbow Pool data for the given locale"
|
||||||
task :download_basic_image_hashes => :environment do
|
task :download_basic_image_hashes => :environment do
|
||||||
Species.find_each do |species|
|
Species.find_each do |species|
|
||||||
pool_url = "http://www.neopets.com/pool/all_pb.phtml"
|
pool_url = "https://www.neopets.com/pool/all_pb.phtml"
|
||||||
pool_options = {
|
pool_options = {
|
||||||
:cookies => {:neologin => URI.encode(ENV['NEOLOGIN'])},
|
:cookies => {:neologin => URI.encode(ENV['NEOLOGIN'])},
|
||||||
:params => {:lang => 'en', :f_species_id => species.id}
|
:params => {:lang => 'en', :f_species_id => species.id}
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace :translate do
|
||||||
desc "Download the Rainbow Pool data for the given locale"
|
desc "Download the Rainbow Pool data for the given locale"
|
||||||
task :pet_attributes => :environment do
|
task :pet_attributes => :environment do
|
||||||
with_given_locale do |neopets_language_code|
|
with_given_locale do |neopets_language_code|
|
||||||
pool_url = "http://www.neopets.com/pool/all_pb.phtml"
|
pool_url = "https://www.neopets.com/pool/all_pb.phtml"
|
||||||
pool_options = {
|
pool_options = {
|
||||||
:cookies => {:neologin => URI.encode(ENV['NEOLOGIN'])},
|
:cookies => {:neologin => URI.encode(ENV['NEOLOGIN'])},
|
||||||
:params => {:lang => neopets_language_code}
|
:params => {:lang => neopets_language_code}
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/usr/bin/env ruby1.8
|
|
||||||
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
|
||||||
|
|
||||||
ENV_PATH = File.expand_path('../../config/environment', __FILE__)
|
|
||||||
BOOT_PATH = File.expand_path('../../config/boot', __FILE__)
|
|
||||||
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
|
||||||
|
|
||||||
require BOOT_PATH
|
|
||||||
require 'rails/commands'
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe BrokenImageReportsController do
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe CampaignsController do
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe ClosetHangersController do
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,19 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe ClosetListsController do
|
|
||||||
|
|
||||||
describe "GET 'new'" do
|
|
||||||
it "should be successful" do
|
|
||||||
get 'new'
|
|
||||||
response.should be_success
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "GET 'create'" do
|
|
||||||
it "should be successful" do
|
|
||||||
get 'create'
|
|
||||||
response.should be_success
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe ClosetPagesController do
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe ItemZoneSetsController do
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe ItemsController do
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,4 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe PetTypesController do
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe SwfAssetsController do
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,15 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
# Specs in this file have access to a helper object that includes
|
|
||||||
# the BrokenImageReportsHelper. For example:
|
|
||||||
#
|
|
||||||
# describe BrokenImageReportsHelper do
|
|
||||||
# describe "string concat" do
|
|
||||||
# it "concats two strings with spaces" do
|
|
||||||
# helper.concat_strings("this","that").should == "this that"
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
describe BrokenImageReportsHelper do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,15 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
# Specs in this file have access to a helper object that includes
|
|
||||||
# the CampaignsHelper. For example:
|
|
||||||
#
|
|
||||||
# describe CampaignsHelper do
|
|
||||||
# describe "string concat" do
|
|
||||||
# it "concats two strings with spaces" do
|
|
||||||
# helper.concat_strings("this","that").should == "this that"
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
describe CampaignsHelper do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,15 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
# Specs in this file have access to a helper object that includes
|
|
||||||
# the ClosetHangersHelper. For example:
|
|
||||||
#
|
|
||||||
# describe ClosetHangersHelper do
|
|
||||||
# describe "string concat" do
|
|
||||||
# it "concats two strings with spaces" do
|
|
||||||
# helper.concat_strings("this","that").should == "this that"
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
describe ClosetHangersHelper do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,15 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
# Specs in this file have access to a helper object that includes
|
|
||||||
# the ClosetListsHelper. For example:
|
|
||||||
#
|
|
||||||
# describe ClosetListsHelper do
|
|
||||||
# describe "string concat" do
|
|
||||||
# it "concats two strings with spaces" do
|
|
||||||
# helper.concat_strings("this","that").should == "this that"
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
describe ClosetListsHelper do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,15 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
# Specs in this file have access to a helper object that includes
|
|
||||||
# the ClosetPagesHelper. For example:
|
|
||||||
#
|
|
||||||
# describe ClosetPagesHelper do
|
|
||||||
# describe "string concat" do
|
|
||||||
# it "concats two strings with spaces" do
|
|
||||||
# helper.concat_strings("this","that").should == "this that"
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
describe ClosetPagesHelper do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require "spec_helper"
|
|
||||||
|
|
||||||
describe DonationMailer do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Campaign do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe ClosetHanger do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe ClosetList do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,22 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Color do
|
|
||||||
specify "should find by id, report name" do
|
|
||||||
Color.find(1).name.should == 'alien'
|
|
||||||
Color.find(2).name.should == 'apple'
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should find by name, report id" do
|
|
||||||
Color.find_by_name('alien').id.should == 1
|
|
||||||
Color.find_by_name('apple').id.should == 2
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "name should be case-insensitive" do
|
|
||||||
Color.find_by_name('Alien').id.should == 1
|
|
||||||
Color.find_by_name('alien').id.should == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "class should have list of basic colors" do
|
|
||||||
Color::Basic.map { |c| c.name }.should == ['blue', 'green', 'red', 'yellow']
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe DonationFeature do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Donation do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe ItemOutfitRelationship do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,250 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Item do
|
|
||||||
context "an item" do
|
|
||||||
before(:each) do
|
|
||||||
@item = Factory.create :item
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should accept string or array for species_support_ids" do
|
|
||||||
@item.species_support_ids = '1,2,3'
|
|
||||||
@item.species_support_ids.should == [1, 2, 3]
|
|
||||||
@item.species_support_ids = [4, 5, 6]
|
|
||||||
@item.species_support_ids.should == [4, 5, 6]
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should provide list of supported species objects" do
|
|
||||||
@item.species_support_ids = [1, 2, 3]
|
|
||||||
@item.supported_species.map { |s| s.name }.should == ['acara', 'aisha', 'blumaroo']
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should provide all species if no support ids" do
|
|
||||||
@item.species_support_ids = ''
|
|
||||||
@item.supported_species.count.should be > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should have many swf_assets through parent_swf_asset_relationships" do
|
|
||||||
SwfAsset.delete_all
|
|
||||||
ParentSwfAssetRelationship.delete_all
|
|
||||||
3.times do |n|
|
|
||||||
swf_asset = Factory.create :swf_asset, :id => n, :url => "http://images.neopets.com/#{n}.swf", :type => 'object'
|
|
||||||
ParentSwfAssetRelationship.create :swf_asset => swf_asset, :item => @item, :swf_asset_type => 'object'
|
|
||||||
end
|
|
||||||
dud_swf_asset = Factory.create :swf_asset, :id => 3, :type => 'object'
|
|
||||||
ParentSwfAssetRelationship.create :swf_asset => dud_swf_asset, :parent_id => 2, :swf_asset_type => 'object'
|
|
||||||
other_type_swf_asset = Factory.create :swf_asset, :id => 4, :type => 'biology'
|
|
||||||
ParentSwfAssetRelationship.create :swf_asset => other_type_swf_asset, :parent_id => 1, :swf_asset_type => 'biology'
|
|
||||||
@item.swf_assets.map(&:id).should == [0, 1, 2]
|
|
||||||
@item.swf_assets.map(&:url).should == ['http://images.neopets.com/0.swf',
|
|
||||||
'http://images.neopets.com/1.swf', 'http://images.neopets.com/2.swf']
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "class" do
|
|
||||||
before :each do
|
|
||||||
Item.delete_all # don't want search returning results from previous tests
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should search name for word" do
|
|
||||||
query_should 'blue',
|
|
||||||
:return => [
|
|
||||||
'A Hat That is Blue',
|
|
||||||
'Blue Hat',
|
|
||||||
'Blueish Hat',
|
|
||||||
'Very Blue Hat'
|
|
||||||
],
|
|
||||||
:not_return => [
|
|
||||||
'Green Hat',
|
|
||||||
'Red Hat'
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should search name for phrase" do
|
|
||||||
query_should '"one two"',
|
|
||||||
:return => [
|
|
||||||
'Zero one two three',
|
|
||||||
'Zero one two',
|
|
||||||
'One two three'
|
|
||||||
],
|
|
||||||
:not_return => [
|
|
||||||
'Zero one three',
|
|
||||||
'Zero two three',
|
|
||||||
'Zero one and two',
|
|
||||||
'Three two one'
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should search name for multiple words" do
|
|
||||||
query_should 'one two',
|
|
||||||
:return => [
|
|
||||||
'Zero one two three',
|
|
||||||
'Zero one two',
|
|
||||||
'One two three',
|
|
||||||
'Zero one and two',
|
|
||||||
'Three two one'
|
|
||||||
],
|
|
||||||
:not_return => [
|
|
||||||
'Zero one three',
|
|
||||||
'Zero two three'
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should search name for words and phrases" do
|
|
||||||
query_should 'zero "one two" three',
|
|
||||||
:return => [
|
|
||||||
'zero one two three',
|
|
||||||
'zero four one two three',
|
|
||||||
'one two zero three',
|
|
||||||
'three zero one two'
|
|
||||||
],
|
|
||||||
:not_return => [
|
|
||||||
'one two three',
|
|
||||||
'zero one two',
|
|
||||||
'three one zero two',
|
|
||||||
'two one three zero'
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should search description for words and phrases" do
|
|
||||||
query_should 'description:zero description:"one two"',
|
|
||||||
:return => [
|
|
||||||
['Green Hat', 'zero one two three'],
|
|
||||||
['Blue Hat', 'five one two four zero']
|
|
||||||
],
|
|
||||||
:not_return => [
|
|
||||||
'Zero one two',
|
|
||||||
['Zero one', 'two'],
|
|
||||||
['Zero', 'One two'],
|
|
||||||
['Three', 'One zero two']
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should search by species" do
|
|
||||||
[[2],[1,2,3],[2,3],[3],[1,3]].each do |ids|
|
|
||||||
Factory.create :item, :species_support_ids => ids
|
|
||||||
end
|
|
||||||
Item.search('species:acara').count.should == 2
|
|
||||||
Item.search('species:aisha').count.should == 3
|
|
||||||
Item.search('species:blumaroo').count.should == 4
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should search by species and words" do
|
|
||||||
Factory.create :item, :name => 'Blue Hat', :species_support_ids => [1]
|
|
||||||
Factory.create :item, :name => 'Very Blue Hat', :species_support_ids => [1,2]
|
|
||||||
Factory.create :item, :name => 'Red Hat', :species_support_ids => [2]
|
|
||||||
Item.search('blue species:acara').count.should == 2
|
|
||||||
Item.search('blue species:aisha').count.should == 1
|
|
||||||
Item.search('red species:acara').count.should == 0
|
|
||||||
Item.search('red species:aisha').count.should == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should return items with no species requirements if a species condition is added" do
|
|
||||||
Factory.create :item, :species_support_ids => [1]
|
|
||||||
Factory.create :item, :species_support_ids => [1,2]
|
|
||||||
Factory.create :item, :species_support_ids => []
|
|
||||||
Item.search('species:acara').count.should == 3
|
|
||||||
Item.search('species:aisha').count.should == 2
|
|
||||||
Item.search('species:acara species:aisha').count.should == 2
|
|
||||||
Item.search('-species:acara').count.should == 0
|
|
||||||
Item.search('-species:aisha').count.should == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should search by only:species" do
|
|
||||||
Factory.create :item, :species_support_ids => [1], :name => 'a'
|
|
||||||
Factory.create :item, :species_support_ids => [1,2], :name => 'b'
|
|
||||||
Factory.create :item, :species_support_ids => [], :name => 'c'
|
|
||||||
Item.search('only:acara').map(&:name).should == ['a']
|
|
||||||
Item.search('only:aisha').count.should == 0
|
|
||||||
Item.search('-only:acara').map(&:name).should == ['b', 'c']
|
|
||||||
Item.search('-only:aisha').map(&:name).should == ['a', 'b', 'c']
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should search by is:nc" do
|
|
||||||
Factory.create :item, :name => 'mall', :rarity_index => 500
|
|
||||||
Factory.create :item, :name => 'also mall', :rarity_index => 500
|
|
||||||
Factory.create :item, :name => 'only mall', :rarity_index => 0, :sold_in_mall => true
|
|
||||||
Factory.create :item, :name => 'not mall', :rarity_index => 400
|
|
||||||
Factory.create :item, :name => 'also not mall', :rarity_index => 101
|
|
||||||
Item.search('is:nc').map(&:name).should == ['mall', 'also mall', 'only mall']
|
|
||||||
Item.search('-is:nc').map(&:name).should == ['not mall', 'also not mall']
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should search by is:pb" do
|
|
||||||
descriptions_by_name = {
|
|
||||||
'Aisha Collar' => 'This item is part of a deluxe paint brush set!',
|
|
||||||
'Christmas Buzz Hat' => 'This item is part of a deluxe paint brush set!',
|
|
||||||
'Blue Hat' => 'This item is a trick and is NOT part of a deluxe paint brush set!',
|
|
||||||
'Green Hat' => 'This hat is green.'
|
|
||||||
}
|
|
||||||
descriptions_by_name.each do |name, description|
|
|
||||||
Factory.create :item, :name => name, :description => description
|
|
||||||
end
|
|
||||||
Item.search('is:pb').map(&:name).should == ['Aisha Collar', 'Christmas Buzz Hat']
|
|
||||||
Item.search('-is:pb').map(&:name).should == ['Blue Hat', 'Green Hat']
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "is:[not 'nc' or 'pb'] should throw ArgumentError" do
|
|
||||||
lambda { Item.search('is:nc') }.should_not raise_error(ArgumentError)
|
|
||||||
lambda { Item.search('is:pb') }.should_not raise_error(ArgumentError)
|
|
||||||
lambda { Item.search('is:awesome') }.should raise_error(ArgumentError)
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should be able to negate word in search" do
|
|
||||||
query_should 'hat -blue',
|
|
||||||
:return => [
|
|
||||||
'Green Hat',
|
|
||||||
'Red Hat',
|
|
||||||
'Blu E Hat',
|
|
||||||
],
|
|
||||||
:not_return => [
|
|
||||||
'Blue Hat',
|
|
||||||
'Green Shirt',
|
|
||||||
'Blue Shirt',
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should be able to negate species in search" do
|
|
||||||
Factory.create :item, :name => 'Blue Hat', :species_support_ids => [1]
|
|
||||||
Factory.create :item, :name => 'Very Blue Hat', :species_support_ids => [1,2]
|
|
||||||
Factory.create :item, :name => 'Red Hat', :species_support_ids => [1,2]
|
|
||||||
Factory.create :item, :name => 'Green Hat', :species_support_ids => [3]
|
|
||||||
Factory.create :item, :name => 'Red Shirt', :species_support_ids => [3]
|
|
||||||
Item.search('hat -species:acara').count.should == 1
|
|
||||||
Item.search('hat -species:aisha').count.should == 2
|
|
||||||
Item.search('hat -species:acara -species:aisha').count.should == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should be able to negate phrase in search" do
|
|
||||||
query_should 'zero -"one two"',
|
|
||||||
:return => [
|
|
||||||
'Zero two one',
|
|
||||||
'One three two zero'
|
|
||||||
],
|
|
||||||
:not_return => [
|
|
||||||
'Zero one two',
|
|
||||||
'One two three zero'
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should raise exception for a query with no conditions" do
|
|
||||||
[
|
|
||||||
lambda { Item.search('').all },
|
|
||||||
lambda { Item.search(nil).all },
|
|
||||||
lambda { Item.search(' ').all }
|
|
||||||
].each { |l| l.should raise_error(ArgumentError) }
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should raise exception for a query that's too short" do
|
|
||||||
lambda { Item.search('e').all }.should raise_error(ArgumentError)
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should not be able to search other attributes thru filters" do
|
|
||||||
lambda { Item.search('id:1').all }.should raise_error(ArgumentError)
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should raise exception if species not found" do
|
|
||||||
lambda { Item.search('species:hurfdurfdurf').all }.should raise_error(ArgumentError)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Outfit do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,18 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe ParentSwfAssetRelationship do
|
|
||||||
context "a relationship" do
|
|
||||||
before(:each) do
|
|
||||||
@relationship = ParentSwfAssetRelationship.new
|
|
||||||
Factory.create :item, :name => 'foo'
|
|
||||||
@relationship.parent_id = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should belong to an swf_asset" do
|
|
||||||
Factory.create :swf_asset, :type => 'object', :id => 1
|
|
||||||
@relationship.swf_asset_id = 1
|
|
||||||
@relationship.swf_asset.id.should == 1
|
|
||||||
@relationship.swf_asset.type.should == 'object'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,18 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe PetState do
|
|
||||||
it "has many swf_assets through parent_swf_asset_relationships" do
|
|
||||||
pet_state = Factory.create :pet_state
|
|
||||||
3.times do |n|
|
|
||||||
swf_asset = Factory.create :swf_asset, :id => n, :url => "http://images.neopets.com/#{n}.swf", :type => 'biology'
|
|
||||||
ParentSwfAssetRelationship.create :swf_asset => swf_asset, :pet_state => pet_state, :swf_asset_type => 'biology'
|
|
||||||
end
|
|
||||||
dud_swf_asset = Factory.create :swf_asset, :id => 3, :type => 'object'
|
|
||||||
ParentSwfAssetRelationship.create :swf_asset => dud_swf_asset, :parent_id => 2, :swf_asset_type => 'biology'
|
|
||||||
other_type_swf_asset = Factory.create :swf_asset, :id => 4, :type => 'biology'
|
|
||||||
ParentSwfAssetRelationship.create :swf_asset => other_type_swf_asset, :parent_id => 1, :swf_asset_type => 'object'
|
|
||||||
pet_state.swf_assets.map(&:id).should == [0, 1, 2]
|
|
||||||
pet_state.swf_assets.map(&:url).should == ['http://images.neopets.com/0.swf',
|
|
||||||
'http://images.neopets.com/1.swf', 'http://images.neopets.com/2.swf']
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,47 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe PetType do
|
|
||||||
context "object" do
|
|
||||||
specify "should return id, body_id in JSON" do
|
|
||||||
pet_type = PetType.create :color_id => 2, :species_id => 3, :body_id => 4
|
|
||||||
pet_type.as_json.should == {:id => 1, :body_id => 4}
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should allow setting species object" do
|
|
||||||
pet_type = PetType.new
|
|
||||||
pet_type.species = Species.find(1)
|
|
||||||
pet_type.species_id.should == 1
|
|
||||||
pet_type.species.id.should == 1
|
|
||||||
pet_type.species.name.should == 'acara'
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should allow setting color object" do
|
|
||||||
pet_type = PetType.new
|
|
||||||
pet_type.color = Color.find(1)
|
|
||||||
pet_type.color_id.should == 1
|
|
||||||
pet_type.color.id.should == 1
|
|
||||||
pet_type.color.name.should == 'alien'
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should return image hash if a basic color" do
|
|
||||||
blue = Color.find_by_name('blue')
|
|
||||||
acara = Species.find_by_name('acara')
|
|
||||||
pet_type = PetType.new :color => blue, :species => acara
|
|
||||||
pet_type.image_hash.should == 'mnbztxxn'
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should return nil for image hash if not a basic color" do
|
|
||||||
asparagus = Color.find_by_name('asparagus')
|
|
||||||
acara = Species.find_by_name('acara')
|
|
||||||
pet_type = PetType.new :color => asparagus, :species => acara
|
|
||||||
pet_type.image_hash.should be nil
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "has many pet states" do
|
|
||||||
pet_type = Factory.create :pet_type
|
|
||||||
[1, 1, 2].each { |x| Factory.create :pet_state, :pet_type_id => x }
|
|
||||||
pet_type.pet_state_ids.should == [1, 2]
|
|
||||||
pet_type.pet_states.map(&:id).should == [1, 2]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,18 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Species do
|
|
||||||
specify "should find by id, report name" do
|
|
||||||
Species.find(1).name.should == 'acara'
|
|
||||||
Species.find(2).name.should == 'aisha'
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "should find by name, report id" do
|
|
||||||
Species.find_by_name('acara').id.should == 1
|
|
||||||
Species.find_by_name('aisha').id.should == 2
|
|
||||||
end
|
|
||||||
|
|
||||||
specify "name should be case-insensitive" do
|
|
||||||
Species.find_by_name('Acara').id.should == 1
|
|
||||||
Species.find_by_name('acara').id.should == 1
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,35 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe SwfAsset do
|
|
||||||
it "belongs to a zone" do
|
|
||||||
asset = Factory.create :swf_asset, :zone_id => 1
|
|
||||||
asset.zone_id.should == 1
|
|
||||||
asset.zone.id.should == 1
|
|
||||||
asset.zone.label.should == 'Music'
|
|
||||||
end
|
|
||||||
|
|
||||||
it "delegates depth to zone" do
|
|
||||||
asset = Factory.create :swf_asset, :zone_id => 1
|
|
||||||
asset.depth.should == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
it "converts neopets URL to impress URL" do
|
|
||||||
asset = Factory.create :swf_asset, :url => 'http://images.neopets.com/cp/items/swf/000/000/012/12211_9969430b3a.swf'
|
|
||||||
asset.local_url.should == 'http://impress.openneo.net/assets/swf/outfit/items/000/000/012/12211_9969430b3a.swf'
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should contain id, depth, zone ID, and local_url as JSON" do
|
|
||||||
asset = Factory.create :swf_asset,
|
|
||||||
:id => 123,
|
|
||||||
:zone_id => 4,
|
|
||||||
:body_id => 234,
|
|
||||||
:url => 'http://images.neopets.com/cp/items/swf/000/000/012/12211_9969430b3a.swf'
|
|
||||||
asset.as_json.should == {
|
|
||||||
:id => 123,
|
|
||||||
:depth => 6,
|
|
||||||
:body_id => 234,
|
|
||||||
:local_url => 'http://impress.openneo.net/assets/swf/outfit/items/000/000/012/12211_9969430b3a.swf',
|
|
||||||
:zone_id => 4
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,8 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Zone do
|
|
||||||
specify "should find by id, report label" do
|
|
||||||
Zone.find(1).label.should == 'Music'
|
|
||||||
Zone.find(3).label.should == 'Background'
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,32 +0,0 @@
|
||||||
# This file is copied to ~/spec when you run 'ruby script/generate rspec'
|
|
||||||
# from the project root directory.
|
|
||||||
ENV["RAILS_ENV"] ||= 'test'
|
|
||||||
require File.dirname(__FILE__) + "/../config/environment" unless defined?(Rails)
|
|
||||||
require 'rspec/rails'
|
|
||||||
|
|
||||||
# Requires supporting files with custom matchers and macros, etc,
|
|
||||||
# in ./support/ and its subdirectories.
|
|
||||||
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
|
||||||
|
|
||||||
Rspec.configure do |config|
|
|
||||||
# == Mock Framework
|
|
||||||
#
|
|
||||||
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
|
||||||
#
|
|
||||||
# config.mock_with :mocha
|
|
||||||
# config.mock_with :flexmock
|
|
||||||
# config.mock_with :rr
|
|
||||||
config.mock_with :rspec
|
|
||||||
|
|
||||||
# If you'd prefer not to run each of your examples within a transaction,
|
|
||||||
# uncomment the following line.
|
|
||||||
# config.use_transactional_examples = false
|
|
||||||
|
|
||||||
def query_should(query, sets)
|
|
||||||
sets.each { |k,v| sets[k] = v.map { |x| x.is_a?(Array) ? x : [x, ''] } }
|
|
||||||
all_sets = sets[:return] + sets[:not_return]
|
|
||||||
all_sets.each { |s| Factory.create :item, :name => s[0], :description => s[1]}
|
|
||||||
returned_sets = Item.search(query).all.map { |i| [i.name, i.description] }.sort
|
|
||||||
returned_sets.should == sets[:return].sort
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe "closet_lists/create.html.erb" do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe "closet_lists/new.html.erb" do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe "petpages/new.html.erb" do
|
|
||||||
pending "add some examples to (or delete) #{__FILE__}"
|
|
||||||
end
|
|
|
@ -1,15 +0,0 @@
|
||||||
Factory.define :item do |i|
|
|
||||||
i.name 'Test Item'
|
|
||||||
i.description 'Test Description'
|
|
||||||
i.thumbnail_url 'http://images.neopets.com/foo.gif'
|
|
||||||
i.zones_restrict ''
|
|
||||||
i.category ''
|
|
||||||
i.add_attribute :type, ''
|
|
||||||
i.rarity 0
|
|
||||||
i.rarity_index 0
|
|
||||||
i.price 0
|
|
||||||
i.weight_lbs 0
|
|
||||||
i.species_support_ids ''
|
|
||||||
i.sold_in_mall false
|
|
||||||
i.last_spidered Time.now
|
|
||||||
end
|
|
|
@ -1,4 +0,0 @@
|
||||||
Factory.define :pet_state do |ps|
|
|
||||||
ps.pet_type_id 1
|
|
||||||
ps.swf_asset_ids_cache '1,2,3'
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
Factory.define :pet_type do |pt|
|
|
||||||
pt.color 8 # blue
|
|
||||||
pt.species 1 # acara
|
|
||||||
pt.body_id 1
|
|
||||||
end
|
|
|
@ -1,8 +0,0 @@
|
||||||
Factory.define :swf_asset do |s|
|
|
||||||
s.url 'http://images.neopets.com/cp/bio/swf/000/000/000/0000_a1b2c3d4e5.swf'
|
|
||||||
s.zone_id 0
|
|
||||||
s.zones_restrict ''
|
|
||||||
s.body_id 0
|
|
||||||
s.add_attribute :type, 'object'
|
|
||||||
s.sequence(:id) { |n| n }
|
|
||||||
end
|
|
BIN
vendor/cache/actioncable-7.0.7.1.gem
vendored
BIN
vendor/cache/actioncable-7.0.7.1.gem
vendored
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue