Compare commits

..

116 Commits

Author SHA1 Message Date
Cesy
cf8fab8ed9 Merge pull request #1080 from Growstuff/dev
Release 16
2016-11-30 15:07:42 +00:00
Mackenzie
376e6c08d3 Merge pull request #1097 from pozorvlak/precompile_assets_in_test
Precompile assets in test
2016-11-30 09:44:15 -05:00
Mackenzie
0cbaac3c75 Merge pull request #1098 from pozorvlak/allow_unadorned_rake_without_db
Run tests with `rake` when DB does not yet exist
2016-11-30 09:43:40 -05:00
Miles Gould
6be9640625 Run tests with rake when DB does not yet exist
Previously, `rake spec` ran the tests whether or not the `growstuff_test`
database existed or not, but `rake` crashed unless it had already been
created. The problem was that `rake` was trying to load the environment,
which required the presence of a DB; `rake spec` was running this with
the `dev` environment, so succeeded if `growstuff_dev` existed, but
`rake` was running everything with the `test` environment, so would fail
if `growstuff_test` did not exist.

This patch adds `db:create` to the dependencies of the `spec` task,
forcing an unadorned `rake` to create all necessary databases first.
2016-11-30 11:35:35 +00:00
Miles Gould
1841548936 Precompile assets in test
According to
https://github.com/teampoltergeist/poltergeist/issues/677#issuecomment-222919584,
a possible cause of the "Request failed to reach server" problem (#901)
is that assets are being compiled on-demand, causing enough of a
slowdown for PhantomJS to think the connection has failed. This turns
off lazy asset compilation in the test environment and precompiles
assets before testing on Travis. We should also turn off lazy asset
compilation in production - see
http://stackoverflow.com/questions/8821864/config-assets-compile-true-in-rails-production-why-not
Our Heroku deployments already run `rake assets:precompile`.
2016-11-30 11:01:25 +00:00
pozorvlak
d3b927b44b Merge pull request #1096 from Growstuff/master
Master to dev for 1092
2016-11-30 09:44:12 +00:00
Shiny
9d68690d86 Merge pull request #1092 from Br3nda/hotfix/1079
Check we have a planted_at ts before using
2016-11-30 17:50:15 +13:00
Brenda Wallace
900e7361c6 Check we have a planted_at ts before doing maths with it 2016-11-30 17:39:26 +13:00
Mackenzie
7b0fdcf007 Merge pull request #1093 from Br3nda/bw/fix-deprecated-methods
Fixes for two calls to deprecated methods
2016-11-29 16:34:32 -05:00
Brenda Wallace
9aa4fa8031 Fixes for two calls to deprecated methods 2016-11-30 10:25:23 +13:00
Mackenzie
391111a5bf Merge pull request #1088 from maco/rename_scientific_name
rename scientific_names.scientific_name to scientific_names.name
2016-11-29 12:04:21 -05:00
Mackenzie
818c8f0c37 Merge pull request #1090 from pozorvlak/indentation-for-great-glory
Fix comment-style weirdness
2016-11-29 09:53:23 -05:00
Mackenzie Morgan
915030e583 whitespace 2016-11-29 09:40:59 -05:00
Mackenzie Morgan
832719b01a merge from upstream dev 2016-11-29 09:37:25 -05:00
Miles Gould
0d8cbc5bf2 Fix comment-style weirdness
We had an inline comment that had been split over two lines; whitespace
fixes made this look very weird.
2016-11-29 10:44:04 +00:00
pozorvlak
bac8f5e4cc Merge pull request #1072 from Br3nda/bw/indentation-for-great-glory
the giant indentation patch of 2016, for great glory
2016-11-29 10:42:24 +00:00
Mackenzie Morgan
69980d9ec6 tests 2016-11-28 22:50:53 -05:00
Mackenzie Morgan
2129b6480d ...that was a guard clause. oops 2016-11-28 22:42:11 -05:00
Mackenzie Morgan
fe860aa1ab clean up some tests 2016-11-28 22:33:00 -05:00
Mackenzie Morgan
a382caab48 clear up redundant else and unneeded returns 2016-11-28 22:08:41 -05:00
Mackenzie Morgan
e1e9a52186 use a guard clause 2016-11-28 22:08:14 -05:00
Mackenzie Morgan
66c8ce78bc further DRY up crops controller 2016-11-28 22:04:32 -05:00
Mackenzie Morgan
e1a2b168c9 rename scientific_names.scientific_name to scientific_names.name
this mirrors alternate_names.name and allows making code more DRY
2016-11-28 21:57:51 -05:00
Brenda Wallace
8763c22284 Merge remote-tracking branch 'upstream/dev' into bw/indentation-for-great-glory
Conflicts:
	app/models/crop.rb
2016-11-29 02:33:30 +00:00
Mackenzie
9ec2f76909 Merge pull request #1086 from maco/sunniness_planted_from
deduplicate sunniness and planted_from functions (Fixes: #1085)
2016-11-28 20:59:52 -05:00
Mackenzie Morgan
b94cb2abd6 deduplicate sunniness and planted_from functions (Fixes: #1085) 2016-11-28 19:57:34 -05:00
Daniel O'Connor
7abafd7b74 Merge pull request #1084 from maco/improve_crop
Improve crop model
2016-11-29 10:27:13 +10:00
Mackenzie Morgan
502862128f break out if/else into discrete blocks 2016-11-28 19:20:35 -05:00
Mackenzie Morgan
96b1e78962 dedup the add from csv code (Fixes: #1082) 2016-11-28 19:12:42 -05:00
Mackenzie
e077f6c7b1 Merge pull request #1076 from Br3nda/bw/poking-travis
Travis file lint and clean
2016-11-28 09:57:26 -05:00
Mackenzie
b25a938936 Merge pull request #1081 from CloCkWeRX/upgrade-gems-nov-2016
Upgrade various gems for Nov 2016
2016-11-28 09:55:54 -05:00
Mackenzie
0952d7d32f Merge pull request #1078 from Br3nda/bw/garden-names-one-line
Limit garden names to one line
2016-11-28 09:55:16 -05:00
Daniel O'Connor
9963502026 bundle update i18n-tasks 2016-11-28 13:55:01 +10:00
Daniel O'Connor
5c2b14376e bundle update terminal-table 2016-11-28 10:43:46 +10:00
Daniel O'Connor
330bc912c1 bundle update bootstrap_form 2016-11-28 10:43:05 +10:00
Daniel O'Connor
bd46c37f07 bundle update activemerchant 2016-11-28 10:42:03 +10:00
Daniel O'Connor
c08c038df1 bundle update active_utils 2016-11-28 10:40:32 +10:00
Daniel O'Connor
0fb9ea7a11 bundle update newrelic_rpm byebug 2016-11-28 10:37:36 +10:00
Daniel O'Connor
89c29ea73c bundle update pg 2016-11-28 10:32:43 +10:00
Daniel O'Connor
9c116f5887 bundle update rspec-rails coveralls capybara-screenshot 2016-11-28 10:31:24 +10:00
Daniel O'Connor
eb1013f925 bundle update jwt kramdown excon 2016-11-28 10:30:02 +10:00
Daniel O'Connor
9bd1484a95 bundle update ruby_parser rb-fsevent redis 2016-11-28 10:29:09 +10:00
Daniel O'Connor
7a90c020fc bundle update thor tins term-ansicolor 2016-11-28 10:28:07 +10:00
Daniel O'Connor
0a69ee682c Merge pull request #1073 from Br3nda/bw/poltergeist-upgrade
Upgrading poltergeist
2016-11-28 10:22:21 +10:00
Daniel O'Connor
8b5c63e898 Merge pull request #1077 from Br3nda/bw/wikipedia-url-regex
Narrow-ed regex on wikipedia url
2016-11-28 10:08:11 +10:00
Cesy
dfe12fd7f8 Merge pull request #1074 from Br3nda/bw/string-interp
String interp doesn't need .to_s in test
2016-11-27 11:02:31 +00:00
Cesy
73a2ac87da Merge pull request #1075 from Br3nda/bw/garden-link
Bugfix: Link to garden, not member
2016-11-27 11:00:49 +00:00
Brenda Wallace
9cce0e39f6 Limit garden names to one line 2016-11-27 14:52:07 +13:00
Brenda Wallace
10c20c7f91 Narrow-ed regex on wikipedia url
and more tests
2016-11-27 14:35:49 +13:00
Brenda Wallace
f52b828abe Use rake to create database 2016-11-27 13:27:45 +13:00
Brenda Wallace
c76fb15cfd Add yamllint settings 2016-11-27 13:24:21 +13:00
Brenda Wallace
167417a711 Indent travis.yml correctly 2016-11-27 13:24:02 +13:00
Brenda Wallace
7fcd3cba8d Changed phantomjs url to project official 2016-11-27 13:22:10 +13:00
Brenda Wallace
9cb58ab0c9 Wrapped the phantomjs downloading in travis.yml 2016-11-27 13:08:53 +13:00
Brenda Wallace
702bbeb724 "[Member]'s garden" link to garden, not member 2016-11-27 10:21:11 +13:00
Brenda Wallace
38fbc52a6f String interp doesn't need .to_s 2016-11-27 10:17:01 +13:00
Cesy
34e86f5881 Merge pull request #1066 from pozorvlak/autodeploy_prod
Auto-deploy to production on successful merge
2016-11-26 08:30:24 +00:00
Brenda Wallace
20c72e1205 Upgrading poltergeist 2016-11-26 13:43:04 +13:00
Brenda Wallace
c02562518d Fixed double handling in harvest.to_s 2016-11-26 12:20:51 +13:00
Brenda Wallace
723ebff923 Spacing fixes 2016-11-26 12:13:17 +13:00
Brenda Wallace
62e7c716dd Removed extra empty blank lines 2016-11-26 12:06:02 +13:00
Brenda Wallace
b17e4eed7d Block indentation fixups 2016-11-26 12:02:47 +13:00
Brenda Wallace
19727144d8 Else statement alignment 2016-11-26 11:57:02 +13:00
Brenda Wallace
e62adc297a Aligning end on branches 2016-11-26 11:55:54 +13:00
Brenda Wallace
2e46cccd21 Hash alignment 2016-11-26 11:52:10 +13:00
Brenda Wallace
bbc19a5436 Array indentation fixed 2016-11-26 11:49:51 +13:00
Brenda Wallace
4cf0f85ee8 Indent the first parameter one step more than the start of the previous line. 2016-11-26 11:46:31 +13:00
Brenda Wallace
d268d2b09e Fixed indentation on comments 2016-11-26 11:45:25 +13:00
Brenda Wallace
200a1c9a84 Closing parenthesis indentation fixed 2016-11-26 11:44:18 +13:00
Brenda Wallace
ebacd83dde Case statement indentation clean up 2016-11-26 11:42:34 +13:00
Brenda Wallace
c878baa886 Indented parameters cleanup 2016-11-26 11:41:07 +13:00
Brenda Wallace
564731667e Fixed up all remaining hash alignment 2016-11-26 11:17:42 +13:00
Brenda Wallace
bae25cfe8f Fixed hash alignment in a funky big DDL 2016-11-26 11:16:55 +13:00
Brenda Wallace
5f3dd04068 Fixed array indentation 2016-11-26 11:00:49 +13:00
Brenda Wallace
2eddaf90cf Fixed access modifier indentation 2016-11-26 11:00:04 +13:00
Brenda Wallace
91d2998507 Fixed multi-line operation indentation 2016-11-26 10:56:23 +13:00
Brenda Wallace
7eb0ee16b9 Indentation for multiline method calls 2016-11-26 10:54:51 +13:00
Brenda Wallace
83392ddda1 Indentation clean ups 2016-11-26 10:51:54 +13:00
pozorvlak
847f4d88d6 Merge pull request #1069 from CloCkWeRX/add-facebook-assets
Add a login splash for facebook
2016-11-25 18:06:02 +00:00
pozorvlak
fb9a1fdfd3 Merge pull request #1061 from Br3nda/bw/long-lines-fixed
Wrapped all lines > 120 chars.
2016-11-25 18:02:22 +00:00
Daniel O'Connor
783406d730 Add a login splash 2016-11-25 09:44:12 +10:00
Brenda Wallace
be67b858b4 Merge remote-tracking branch 'upstream/dev' into bw/long-lines-fixed
Conflicts:
	lib/tasks/growstuff.rake
2016-11-25 08:18:18 +13:00
Miles Gould
a796ba904a Merge branch 'Br3nda-bw/reduce-complexity' into dev 2016-11-24 19:06:31 +00:00
Miles Gould
012f2f0cfa Merge branch 'bw/reduce-complexity' of https://github.com/Br3nda/growstuff into Br3nda-bw/reduce-complexity 2016-11-24 19:00:06 +00:00
pozorvlak
3e8c61c0c3 Merge pull request #1064 from Br3nda/bw/normalise-translations
Normalise translation file
2016-11-24 18:55:10 +00:00
Miles Gould
844f68ef4c Auto-deploy to production on successful merge
I *think* this is all that's necessary, though it's a bit hard to test
:-)
2016-11-24 18:48:01 +00:00
Brenda Wallace
975deab4b2 Normalise translation file 2016-11-23 20:24:02 +13:00
Brenda Wallace
fb6f1ac0a8 Changed whitelisting of what can have photos 2016-11-21 10:05:52 +13:00
Brenda Wallace
069343803e List of types that can have photos in own method 2016-11-20 21:46:58 +13:00
Brenda Wallace
36d38fe624 Turn off frozen literals requirement 2016-11-20 21:39:51 +13:00
Brenda Wallace
0d6680f574 Disabling rails-pos-args, and documentation
in rubocop
2016-11-20 21:37:10 +13:00
Brenda Wallace
dac2343b68 Further code duplication reduction 2016-11-20 21:18:07 +13:00
Brenda Wallace
f24e02fd11 reduced code duplication again in photos cont spec 2016-11-20 21:13:57 +13:00
Brenda Wallace
dddc7b020d Corrected description in spec 2016-11-20 21:13:33 +13:00
Brenda Wallace
12a9a0b97d one more check no alert was generated 2016-11-20 21:13:08 +13:00
Brenda Wallace
6a8f48693b Reduce code duplication in photos cont spec 2016-11-20 21:12:43 +13:00
Brenda Wallace
50a0668c1d Check no alert message was generated 2016-11-20 21:11:54 +13:00
Brenda Wallace
a7e88a55b3 Spec for trying to attach photo when not allowed. 2016-11-20 21:03:08 +13:00
Brenda Wallace
8012d9f6a8 Whitelist which items can have photos 2016-11-20 21:02:43 +13:00
Brenda Wallace
73a050df13 before_filter becomes before_action
in photos controller
2016-11-20 20:29:45 +13:00
Brenda Wallace
d0a1a113b6 Multi-line block changed from {} to do end 2016-11-20 20:29:01 +13:00
Brenda Wallace
a8bffd3bce White space fix in spec 2016-11-20 20:28:34 +13:00
Brenda Wallace
f6aac07c3d Flatten params passed in photos controller spec 2016-11-20 20:27:59 +13:00
Brenda Wallace
72f1d83af4 Removed a bunch of blank lines 2016-11-20 20:19:14 +13:00
Brenda Wallace
138080c4d4 Tabulation fix 2016-11-20 20:18:20 +13:00
Brenda Wallace
cf70bfebe9 Further simplified photos controller 2016-11-20 20:17:27 +13:00
Brenda Wallace
5fc1ab9c60 Reduced code duplication in growstuff.rake 2016-11-20 19:35:17 +13:00
Brenda Wallace
6078734136 Merge remote-tracking branch 'upstream/dev' into bw/reduce-complexity 2016-11-20 19:25:30 +13:00
Brenda Wallace
917e33bccf Merge remote-tracking branch 'upstream/dev' into bw/long-lines-fixed 2016-11-20 19:24:53 +13:00
Brenda Wallace
810fe14c69 Highest percieved complexity is now 10 2016-11-20 09:17:42 +13:00
Brenda Wallace
f4a26d0580 has_item_id? renamed to item_id? 2016-11-20 09:06:04 +13:00
Brenda Wallace
0a54c2d986 Moved to method: collection to use for photos 2016-11-20 09:05:29 +13:00
Brenda Wallace
9c4f011fbc Reduced percieved complexity in photos_controller.rb 2016-11-19 22:28:38 +13:00
Brenda Wallace
951727e266 Removed offense count comment from rubocop.yml - has fixed 2016-11-19 13:58:45 +13:00
Brenda Wallace
2872a1c29d Wrapped all long lines.
reduced rubocop's line length limit to 120
2016-11-17 22:02:18 +13:00
Brenda Wallace
fd29a94d6e Whitespace fixes in Gemfile 2016-11-17 21:52:52 +13:00
306 changed files with 1323 additions and 3491 deletions

View File

@@ -8,9 +8,22 @@ AllCops:
- 'db/schema.rb'
- 'vendor/**/*'
Style/FileName:
Exclude:
- 'Gemfile'
- 'Gemfile.lock'
Style/StringLiterals:
Enabled: false
Style/MultilineMethodCallIndentation:
EnforcedStyle: indented
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
# SupportedStyles: with_first_parameter, with_fixed_indentation
Style/AlignParameters:
EnforcedStyle: with_fixed_indentation
Metrics/MethodLength:
Description: 'Avoid methods longer than 30 lines of code.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#short-methods'
@@ -37,12 +50,19 @@ Metrics/ClassLength:
Metrics/CyclomaticComplexity:
Max: 11
# Offense count: 1108
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives.
# URISchemes: http, https
Metrics/LineLength:
Max: 223
Max: 120
# Offense count: 8
Metrics/PerceivedComplexity:
Max: 12
Max: 10
# See https://github.com/bbatsov/rubocop/issues/3629
Rails/HttpPositionalArguments:
Enabled: false
Style/Documentation:
Enabled: false
Style/FrozenStringLiteralComment:
Enabled: false

View File

File diff suppressed because it is too large Load Diff

View File

@@ -11,21 +11,27 @@ env:
global:
secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4="
rvm:
- 2.3.1
- 2.3.1
before_install:
- export PATH=$PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64/bin:$PATH
- if [ $(phantomjs --version) != '2.1.1' ]; then rm -rf $PWD/travis_phantomjs; mkdir -p $PWD/travis_phantomjs; fi
- if [ $(phantomjs --version) != '2.1.1' ]; then wget https://assets.membergetmember.co/software/phantomjs-2.1.1-linux-x86_64.tar.bz2 -O $PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2; fi
- if [ $(phantomjs --version) != '2.1.1' ]; then tar -xvf $PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C $PWD/travis_phantomjs; fi
- >
if [ $(phantomjs --version) != '2.1.1' ]; then
PHANTOM_URL=https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2;
rm -rf $PWD/travis_phantomjs;
mkdir -p $PWD/travis_phantomjs;
wget $PHANTOM_URL -O $PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2;
tar -xvf $PWD/travis_phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C $PWD/travis_phantomjs;
fi
- phantomjs --version
before_script:
- psql -c 'create database growstuff_test;' -U postgres
- bundle exec rake db:create db:migrate db:test:prepare
- bundle exec rake assets:precompile
script:
- bundle exec rubocop --display-cop-names --rails
- script/gemfile_check
- bundle exec script/check_contributors_md
- bundle exec rake db:migrate --trace
- bundle exec rspec spec/
- bundle exec rubocop --display-cop-names --rails
- script/gemfile_check
- bundle exec script/check_contributors_md
- bundle exec rake db:migrate --trace
- bundle exec rspec spec/
services:
- elasticsearch
before_deploy:
@@ -38,6 +44,7 @@ deploy:
repo: Growstuff/growstuff
app:
dev: growstuff-staging
master: growstuff-prod
travis_deploy: tranquil-basin-3130
travis_containers: tranquil-basin-3130
run:

7
.yamllint Normal file
View File

@@ -0,0 +1,7 @@
extends: relaxed
rules:
# 80 chars should be enough, but don't fail if a line is longer
line-length:
max: 150
level: warning

View File

@@ -110,14 +110,17 @@ group :development, :test do
gem 'capybara' # integration tests
gem 'capybara-email' # integration tests for email
gem 'capybara-screenshot' # for test debugging
gem 'poltergeist', '~> 1.6' # for headless JS testing
gem 'poltergeist' # for headless JS testing
gem 'i18n-tasks' # adds tests for finding missing and unused translations
gem 'selenium-webdriver'
gem "codeclimate-test-reporter", group: :test, require: nil
gem "active_merchant-paypal-bogus-gateway"
gem 'rubocop', require: false
end
group :test do
gem 'codeclimate-test-reporter', require: false
end
group :travis do
gem 'heroku-api'
end

View File

@@ -24,13 +24,13 @@ GEM
actionpack
active_merchant-paypal-bogus-gateway (0.1.0)
activemerchant
active_utils (3.2.2)
active_utils (3.2.3)
activesupport (>= 3.2, < 5.1.0)
i18n
activejob (4.2.7.1)
activesupport (= 4.2.7.1)
globalid (>= 0.3.0)
activemerchant (1.60.0)
activemerchant (1.61.0)
activesupport (>= 3.2.14, < 5.1)
builder (>= 2.1.2, < 4.0.0)
i18n (>= 0.6.9)
@@ -48,7 +48,8 @@ GEM
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.4.0)
addressable (2.5.0)
public_suffix (~> 2.0, >= 2.0.2)
arel (6.0.3)
ast (2.3.0)
autoprefixer-rails (6.4.0.2)
@@ -70,11 +71,11 @@ GEM
bootstrap-sass (3.3.7)
autoprefixer-rails (>= 5.2.1)
sass (>= 3.3.4)
bootstrap_form (2.5.0)
bootstrap_form (2.5.2)
builder (3.2.2)
byebug (9.0.5)
byebug (9.0.6)
cancancan (1.15.0)
capybara (2.8.0)
capybara (2.10.1)
addressable
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
@@ -84,7 +85,7 @@ GEM
capybara-email (2.5.0)
capybara (~> 2.4)
mail
capybara-screenshot (1.0.13)
capybara-screenshot (1.0.14)
capybara (>= 1.0, < 3)
launchy
childprocess (0.5.9)
@@ -123,10 +124,10 @@ GEM
sass-rails (>= 4.0.3)
concurrent-ruby (1.0.2)
connection_pool (2.2.0)
coveralls (0.8.15)
coveralls (0.8.16)
json (>= 1.8, < 3)
simplecov (~> 0.12.0)
term-ansicolor (~> 1.3)
term-ansicolor (~> 1.3.0)
thor (~> 0.19.1)
tins (>= 1.6.0, < 2)
csv_shaper (1.3.0)
@@ -160,7 +161,7 @@ GEM
faraday
multi_json
erubis (2.7.0)
excon (0.51.0)
excon (0.54.0)
execjs (2.7.0)
factory_girl (4.7.0)
activesupport (>= 3.0.0)
@@ -222,7 +223,7 @@ GEM
httparty (0.14.0)
multi_xml (>= 0.5.2)
i18n (0.7.0)
i18n-tasks (0.9.5)
i18n-tasks (0.9.6)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
easy_translate (>= 0.5.0)
@@ -242,12 +243,12 @@ GEM
railties (>= 3.2)
sprockets-rails
json (1.8.3)
jwt (1.5.4)
jwt (1.5.6)
kaminari (0.17.0)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.10.0)
kramdown (1.12.0)
kramdown (1.13.1)
launchy (2.4.3)
addressable (~> 2.3)
leaflet-markercluster-rails (0.7.0)
@@ -271,15 +272,14 @@ GEM
mime-types-data (3.2016.0521)
mimemagic (0.3.2)
mini_portile2 (2.1.0)
minitest (5.9.0)
minitest (5.9.1)
multi_json (1.11.3)
multi_xml (0.5.5)
multipart-post (2.0.0)
nenv (0.3.0)
newrelic_rpm (3.16.1.320)
nokogiri (1.6.8)
newrelic_rpm (3.17.1.326)
nokogiri (1.6.8.1)
mini_portile2 (~> 2.1.0)
pkg-config (~> 1.1.7)
notiffany (0.1.1)
nenv (~> 0.1)
shellany (~> 0.0)
@@ -314,13 +314,12 @@ GEM
cocaine (~> 0.5.5)
mime-types
mimemagic (~> 0.3.0)
parser (2.3.1.2)
parser (2.3.2.0)
ast (~> 2.2)
pg (0.18.4)
pkg-config (1.1.7)
pg (0.19.0)
plupload-rails (1.2.1)
rails (>= 3.1)
poltergeist (1.10.0)
poltergeist (1.11.0)
capybara (~> 2.1)
cliver (~> 0.3.1)
websocket-driver (>= 0.2.0)
@@ -329,9 +328,10 @@ GEM
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
public_suffix (2.0.4)
quiet_assets (1.1.0)
railties (>= 3.1, < 5.0)
rack (1.6.4)
rack (1.6.5)
rack-protection (1.5.3)
rack
rack-test (0.6.3)
@@ -370,11 +370,11 @@ GEM
thor (>= 0.18.1, < 2.0)
rainbow (2.1.0)
raindrops (0.17.0)
rake (11.2.2)
rb-fsevent (0.9.7)
rake (11.3.0)
rb-fsevent (0.9.8)
rb-inotify (0.9.7)
ffi (>= 0.5.0)
redis (3.3.1)
redis (3.3.2)
responders (2.3.0)
railties (>= 4.2.0, < 5.1)
rspec (3.5.0)
@@ -385,7 +385,7 @@ GEM
activemodel (>= 3.0)
activesupport (>= 3.0)
rspec-mocks (>= 2.99, < 4.0)
rspec-core (3.5.2)
rspec-core (3.5.4)
rspec-support (~> 3.5.0)
rspec-expectations (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
@@ -393,7 +393,7 @@ GEM
rspec-mocks (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.5.0)
rspec-rails (3.5.1)
rspec-rails (3.5.2)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
@@ -411,7 +411,7 @@ GEM
ruby-progressbar (1.8.1)
ruby-units (2.0.1)
ruby_dep (1.4.0)
ruby_parser (3.8.2)
ruby_parser (3.8.3)
sexp_processor (~> 4.1)
rubyzip (1.2.0)
sass (3.4.22)
@@ -453,12 +453,13 @@ GEM
sprockets (>= 3.0.0)
term-ansicolor (1.3.2)
tins (~> 1.0)
terminal-table (1.6.0)
thor (0.19.1)
terminal-table (1.7.3)
unicode-display_width (~> 1.1.1)
thor (0.19.3)
thread (0.2.2)
thread_safe (0.3.5)
tilt (2.0.5)
tins (1.12.0)
tins (1.13.0)
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (2.7.2)
@@ -540,7 +541,7 @@ DEPENDENCIES
omniauth-flickr (>= 0.0.15)
omniauth-twitter
pg
poltergeist (~> 1.6)
poltergeist
pry
quiet_assets
rails (~> 4.2.1)

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

View File

@@ -43,5 +43,4 @@ class AccountsController < ApplicationController
def account_params
params.require(:account).permit(:account_type_id, :member_id, :paid_until)
end
end

View File

@@ -8,7 +8,7 @@ class Admin::OrdersController < ApplicationController
def search
authorize! :manage, :all
@orders = Order.search({by: params[:search_by], for: params[:search_text]})
@orders = Order.search({ by: params[:search_by], for: params[:search_text] })
if @orders.empty?
flash[:alert] = "Couldn't find order with #{params[:search_by]} = #{params[:search_text]}"
@@ -17,6 +17,5 @@ class Admin::OrdersController < ApplicationController
respond_to do |format|
format.html # index.html.haml
end
end
end

View File

@@ -14,7 +14,7 @@ class ApplicationController < ActionController::Base
request.path != "/members/confirmation" &&
request.path != "/members/sign_out" &&
!request.xhr?)
store_location_for(:member, request.fullpath)
store_location_for(:member, request.fullpath)
end
end
@@ -73,10 +73,9 @@ class ApplicationController < ActionController::Base
:bio, :location, :latitude, :longitude,
# email settings
:show_email, :newsletter, :send_notification_email, :send_planting_reminder,
#update password
# update password
:current_password
)
end
end
end

View File

@@ -10,15 +10,15 @@ class AuthenticationsController < ApplicationController
name = Growstuff::OauthSignupAction.new.determine_name(auth)
@authentication = current_member.authentications
.create_with(
name: name,
token: auth['credentials']['token'],
secret: auth['credentials']['secret']
)
.find_or_create_by(
provider: auth['provider'],
uid: auth['uid'],
name: name)
.create_with(
name: name,
token: auth['credentials']['token'],
secret: auth['credentials']['secret']
)
.find_or_create_by(
provider: auth['provider'],
uid: auth['uid'],
name: name)
flash[:notice] = "Authentication successful."
else

View File

@@ -11,11 +11,11 @@ class CropsController < ApplicationController
@sort = params[:sort]
if @sort == 'alpha'
# alphabetical order
@crops = Crop.includes(:scientific_names, {plantings: :photos})
@crops = Crop.includes(:scientific_names, { plantings: :photos })
@paginated_crops = @crops.approved.paginate(page: params[:page])
else
# default to sorting by popularity
@crops = Crop.popular.includes(:scientific_names, {plantings: :photos})
@crops = Crop.popular.includes(:scientific_names, { plantings: :photos })
@paginated_crops = @crops.approved.paginate(page: params[:page])
end
@@ -37,14 +37,14 @@ class CropsController < ApplicationController
# GET /crops/wrangle
def wrangle
@approval_status = params[:approval_status]
case @approval_status
when "pending"
@crops = Crop.pending_approval
when "rejected"
@crops = Crop.rejected
else
@crops = Crop.recent
end
@crops = case @approval_status
when "pending"
Crop.pending_approval
when "rejected"
Crop.rejected
else
Crop.recent
end
@crops = @crops.paginate(page: params[:page])
@@ -77,7 +77,7 @@ class CropsController < ApplicationController
# GET /crops/1
# GET /crops/1.json
def show
@crop = Crop.includes(:scientific_names, {plantings: :photos}).find(params[:id])
@crop = Crop.includes(:scientific_names, { plantings: :photos }).find(params[:id])
@posts = @crop.posts.paginate(page: params[:page])
respond_to do |format|
@@ -90,10 +90,10 @@ class CropsController < ApplicationController
}
}
render json: @crop.to_json(include: {
plantings: {
include: owner_structure
}
})
plantings: {
include: owner_structure
}
})
end
end
end
@@ -116,13 +116,11 @@ class CropsController < ApplicationController
@crop = Crop.find(params[:id])
@crop.alternate_names.build if @crop.alternate_names.blank?
@crop.scientific_names.build if @crop.scientific_names.blank?
end
# POST /crops
# POST /crops.json
def create
@crop = Crop.new(crop_params)
if current_member.has_role? :crop_wrangler
@@ -137,10 +135,10 @@ class CropsController < ApplicationController
respond_to do |format|
if @crop.save
params[:alt_name].each do |index, value|
@crop.alternate_names.create(name: value, creator_id: current_member.id)
create_name('alternate', value)
end
params[:sci_name].each do |index, value|
@crop.scientific_names.create(scientific_name: value, creator_id: current_member.id)
create_name('scientific', value)
end
unless current_member.has_role? :crop_wrangler
Role.crop_wranglers.each do |w|
@@ -168,22 +166,8 @@ class CropsController < ApplicationController
respond_to do |format|
if @crop.update(crop_params)
if !params[:alt_name].nil?
@crop.alternate_names.each do |alt_name|
alt_name.destroy
end
params[:alt_name].each do |index, value|
alt_name = @crop.alternate_names.create(name: value, creator_id: current_member.id)
end
@crop.scientific_names.each do |sci_name|
sci_name.destroy
end
params[:sci_name].each do |index, value|
sci_name = @crop.scientific_names.create(scientific_name: value, creator_id: current_member.id)
end
end
recreate_names('alt_name', 'alternate')
recreate_names('sci_name', 'scientific')
if previous_status == "pending"
requester = @crop.requester
@@ -214,7 +198,34 @@ class CropsController < ApplicationController
private
def recreate_names(param_name, name_type)
return unless params[param_name].present?
destroy_names(name_type)
params[param_name].each do |index, value|
create_name(name_type, value)
end
end
def destroy_names(name_type)
@crop.send("#{name_type}_names").each do |alt_name|
alt_name.destroy
end
end
def create_name(name_type, value)
@crop.send("#{name_type}_names").create(name: value, creator_id: current_member.id)
end
def crop_params
params.require(:crop).permit(:en_wikipedia_url, :name, :parent_id, :creator_id, :approval_status, :request_notes, :reason_for_rejection, :rejection_notes, scientific_names_attributes: [:scientific_name, :_destroy, :id])
params.require(:crop).permit(:en_wikipedia_url,
:name,
:parent_id,
:creator_id,
:approval_status,
:request_notes,
:reason_for_rejection,
:rejection_notes, scientific_names_attributes: [:scientific_name,
:_destroy,
:id])
end
end

View File

@@ -5,11 +5,10 @@ class FollowsController < ApplicationController
# POST /follows
def create
@follow = current_member.follows.build(followed_id: follow_params[:followed_id])
if @follow.save
flash[:notice] = "Followed #{ @follow.followed.login_name }"
flash[:notice] = "Followed #{@follow.followed.login_name}"
redirect_to :back
else
flash[:error] = "Already following or error while following."
@@ -23,7 +22,7 @@ class FollowsController < ApplicationController
unfollowed_name = @follow.followed.login_name
@follow.destroy
flash[:notice] = "Unfollowed #{ unfollowed_name }"
flash[:notice] = "Unfollowed #{unfollowed_name}"
redirect_to root_path
end

View File

@@ -2,7 +2,6 @@ class GardensController < ApplicationController
before_filter :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /gardens
# GET /gardens.json
def index
@@ -87,7 +86,9 @@ class GardensController < ApplicationController
expire_fragment("homepage_stats")
respond_to do |format|
format.html { redirect_to gardens_by_owner_path(owner: @garden.owner), notice: 'Garden was successfully deleted.' }
format.html do
redirect_to gardens_by_owner_path(owner: @garden.owner), notice: 'Garden was successfully deleted.'
end
format.json { head :no_content }
end
end
@@ -96,6 +97,6 @@ class GardensController < ApplicationController
def garden_params
params.require(:garden).permit(:name, :slug, :owner_id, :description, :active,
:location, :latitude, :longitude, :area, :area_unit)
:location, :latitude, :longitude, :area, :area_unit)
end
end

View File

@@ -7,13 +7,13 @@ class HarvestsController < ApplicationController
def index
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
if @owner
@harvests = @owner.harvests.includes(:owner, :crop)
elsif @crop
@harvests = @crop.harvests.includes(:owner, :crop)
else
@harvests = Harvest.includes(:owner, :crop)
end
@harvests = if @owner
@owner.harvests.includes(:owner, :crop)
elsif @crop
@crop.harvests.includes(:owner, :crop)
else
Harvest.includes(:owner, :crop)
end
respond_to do |format|
format.html { @harvests = @harvests.paginate(page: params[:page]) }
@@ -32,7 +32,7 @@ class HarvestsController < ApplicationController
@harvest = Harvest.new('harvested_at' => Date.today)
# using find_by_id here because it returns nil, unlike find
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
respond_to do |format|
format.html # new.html.erb
@@ -95,6 +95,6 @@ class HarvestsController < ApplicationController
def harvest_params
params.require(:harvest).permit(:crop_id, :harvested_at, :description, :owner_id,
:quantity, :unit, :weight_quantity, :weight_unit, :plant_part_id, :slug, :si_weight)
:quantity, :unit, :weight_quantity, :weight_unit, :plant_part_id, :slug, :si_weight)
end
end

View File

@@ -2,7 +2,6 @@ class HomeController < ApplicationController
skip_authorize_resource
def index
# we were previously generating a lot of instance variables like
# @members_count and @interesting_crops in here, but now we call
# the relevant class methods directly in the view, so that fragment
@@ -12,5 +11,4 @@ class HomeController < ApplicationController
format.html # index.html.haml
end
end
end

View File

@@ -7,15 +7,19 @@ class MembersController < ApplicationController
def index
@sort = params[:sort]
if @sort == 'recently_joined'
@members = Member.confirmed.recently_joined.paginate(page: params[:page])
else
@members = Member.confirmed.paginate(page: params[:page])
end
@members = if @sort == 'recently_joined'
Member.confirmed.recently_joined.paginate(page: params[:page])
else
Member.confirmed.paginate(page: params[:page])
end
respond_to do |format|
format.html # index.html.haml
format.json { render json: @members.to_json(only: [:id, :login_name, :slug, :bio, :created_at, :location, :latitude, :longitude]) }
format.json {
render json: @members.to_json(only: [
:id, :login_name, :slug, :bio, :created_at, :location, :latitude, :longitude
])
}
end
end
@@ -32,7 +36,11 @@ class MembersController < ApplicationController
respond_to do |format|
format.html # show.html.haml
format.json { render json: @member.to_json(only: [:id, :login_name, :bio, :created_at, :slug, :location, :latitude, :longitude]) }
format.json {
render json: @member.to_json(only: [
:id, :login_name, :bio, :created_at, :slug, :location, :latitude, :longitude
])
}
format.rss { render(
layout: false,
locals: { member: @member }

View File

@@ -10,6 +10,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
create
end
def failure
flash[:alert] = "Authentication failed."
redirect_to request.env['omniauth.origin'] || "/"
@@ -27,7 +28,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
@authentication = action.establish_authentication(auth, member)
unless action.member_created?
sign_in_and_redirect member, event: :authentication #this will throw if @user is not activated
sign_in_and_redirect member, event: :authentication # this will throw if @user is not activated
set_flash_message(:notice, :success, kind: auth['provider']) if is_navigational_format?
else
raise "Invalid provider" unless ['facebook', 'twitter', 'flickr'].index(auth['provider'].to_s)

View File

@@ -49,7 +49,6 @@ class OrdersController < ApplicationController
format.html { render action: "show" }
end
end
end
def complete
@@ -78,7 +77,6 @@ class OrdersController < ApplicationController
respond_to do |format|
format.html # new.html.erb
end
end
def cancel

View File

@@ -1,6 +1,6 @@
class PasswordsController < Devise::PasswordsController
protected
protected
def after_resetting_password_path_for(resource)
root_path
end

View File

@@ -1,5 +1,5 @@
class PhotosController < ApplicationController
before_filter :authenticate_member!, except: [:index, :show]
before_action :authenticate_member!, except: [:index, :show]
load_and_authorize_resource
# GET /photos
@@ -47,37 +47,12 @@ class PhotosController < ApplicationController
# POST /photos
# POST /photos.json
def create
@photo = Photo.find_by_flickr_photo_id(params[:photo][:flickr_photo_id]) ||
Photo.new(photo_params)
@photo.owner_id = current_member.id
@photo.set_flickr_metadata
collection = case params[:type]
when 'garden'
@photo.gardens
when 'planting'
@photo.plantings
when 'harvest'
@photo.harvests
else
nil
end
if collection && has_item_id
item = params[:type].camelcase.constantize.find_by_id(params[:id])
if item && member_owns_item(item)
collection << item unless collection.include?(item)
else
flash[:alert] = "Could not find this item owned by you"
end
else
flash[:alert] = "Missing or invalid type or id parameter"
end
find_or_create_photo_from_flickr_photo
add_photo_to_collection
respond_to do |format|
if @photo.save
format.html { redirect_to @photo, notice: 'Photo was successfully added.' }
if @photo.present? && @photo.save
format.html { redirect_to photo_path(@photo), notice: 'Photo was successfully added.' }
format.json { render json: @photo, status: :created, location: @photo }
else
format.html { render action: "new" }
@@ -117,16 +92,57 @@ class PhotosController < ApplicationController
private
def has_item_id
def item_id?
params.key? :id
end
def member_owns_item(item)
item.owner.id == current_member.id
def flickr_photo_id_param
params[:photo][:flickr_photo_id]
end
def photo_params
params.require(:photo).permit(:flickr_photo_id, :owner_id, :title, :license_name,
:license_url, :thumbnail_url, :fullsize_url, :link_url)
:license_url, :thumbnail_url, :fullsize_url, :link_url)
end
def find_or_create_photo_from_flickr_photo
@photo = Photo.find_by(flickr_photo_id: flickr_photo_id_param)
@photo = Photo.new(photo_params) unless @photo
@photo.owner_id = current_member.id
@photo.set_flickr_metadata
@photo
end
def which_collection?
case params[:type]
when "garden" then @photo.gardens
when "harvest" then @photo.harvests
when "planting" then @photo.plantings
else raise "Invalid type"
end
end
def add_photo_to_collection
collection = which_collection?
unless collection && item_id?
flash[:alert] = "Missing or invalid type or id parameter"
return
end
item = find_item_for_photo!
collection << item unless collection.include?(item)
rescue
flash[:alert] = "Could not find this item owned by you"
end
def find_item_for_photo!
item_class = case params[:type]
when "garden" then Garden
when "harvest" then Harvest
when "planting" then Planting
else raise "Invalid type"
end
item_class.find_by!(id: params[:id], owner_id: current_member.id)
end
end

View File

@@ -5,7 +5,11 @@ class PlacesController < ApplicationController
respond_to do |format|
format.html
# json response is whatever we want to map here
format.json { render json: Member.located.to_json(only: [:id, :login_name, :slug, :location, :latitude, :longitude]) }
format.json do
render json: Member.located.to_json(only: [
:id, :login_name, :slug, :location, :latitude, :longitude
])
end
end
end
@@ -16,7 +20,11 @@ class PlacesController < ApplicationController
@nearby_members = Member.nearest_to(params[:place])
respond_to do |format|
format.html # show.html.haml
format.json { render json: @nearby_members.to_json(only: [:id, :login_name, :slug, :location, :latitude, :longitude]) }
format.json do
render json: @nearby_members.to_json(only: [
:id, :login_name, :slug, :location, :latitude, :longitude
])
end
end
end
@@ -35,5 +43,4 @@ class PlacesController < ApplicationController
end
end
end
end

View File

@@ -7,18 +7,18 @@ class PlantingsController < ApplicationController
def index
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
if @owner
@plantings = @owner.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page])
elsif @crop
@plantings = @crop.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page])
else
@plantings = Planting.includes(:owner, :crop, :garden).paginate(page: params[:page])
end
@plantings = if @owner
@owner.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page])
elsif @crop
@crop.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page])
else
Planting.includes(:owner, :crop, :garden).paginate(page: params[:page])
end
respond_to do |format|
format.html { @plantings = @plantings.paginate(page: params[:page]) }
format.json { render json: @plantings }
format.rss { render layout: false } #index.rss.builder
format.rss { render layout: false } # index.rss.builder
format.csv do
specifics = (@owner ? "#{@owner.login_name}-" : @crop ? "#{@crop.name}-" : nil)
@filename = "Growstuff-#{specifics}Plantings-#{Time.zone.now.to_s(:number)}.csv"
@@ -71,7 +71,8 @@ class PlantingsController < ApplicationController
respond_to do |format|
if @planting.save
@planting.update_attribute(:days_before_maturity, update_days_before_maturity(@planting, planting_params[:crop_id]))
@planting.update_attribute(:days_before_maturity,
update_days_before_maturity(@planting, planting_params[:crop_id]))
format.html { redirect_to @planting, notice: 'Planting was successfully created.' }
format.json { render json: @planting, status: :created, location: @planting }
expire_fragment("homepage_stats")
@@ -90,7 +91,8 @@ class PlantingsController < ApplicationController
respond_to do |format|
if @planting.update(planting_params)
@planting.update_attribute(:days_before_maturity, update_days_before_maturity(@planting, planting_params[:crop_id]))
@planting.update_attribute(:days_before_maturity,
update_days_before_maturity(@planting, planting_params[:crop_id]))
format.html { redirect_to @planting, notice: 'Planting was successfully updated.' }
format.json { head :no_content }
else
@@ -118,8 +120,8 @@ class PlantingsController < ApplicationController
def planting_params
params.require(:planting).permit(:crop_id, :description, :garden_id, :planted_at,
:quantity, :sunniness, :planted_from, :owner_id, :finished,
:finished_at)
:quantity, :sunniness, :planted_from, :owner_id, :finished,
:finished_at)
end
def update_days_before_maturity(planting, crop_id)

View File

@@ -7,16 +7,16 @@ class PostsController < ApplicationController
def index
@author = Member.find_by_slug(params[:author])
if @author
@posts = @author.posts.includes(:author, { comments: :author }).paginate(page: params[:page])
else
@posts = Post.includes(:author, { comments: :author }).paginate(page: params[:page])
end
@posts = if @author
@author.posts.includes(:author, { comments: :author }).paginate(page: params[:page])
else
Post.includes(:author, { comments: :author }).paginate(page: params[:page])
end
respond_to do |format|
format.html # index.html.haml
format.json { render json: @posts }
format.rss { render layout: false } #index.rss.builder
format.rss { render layout: false } # index.rss.builder
end
end

View File

@@ -74,6 +74,6 @@ class ProductsController < ApplicationController
def product_params
params.require(:product).permit(:description, :min_price, :recommended_price, :name,
:account_type_id, :paid_months)
:account_type_id, :paid_months)
end
end

View File

@@ -8,23 +8,22 @@ class RegistrationsController < Devise::RegistrationsController
render "edit"
end
# we need this subclassed method so that Devise doesn't force people to
# change their password every time they want to edit their settings.
# we also check that they give their current password to change their password.
# Code copied from
# https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-account-without-providing-a-password
# we need this subclassed method so that Devise doesn't force people to
# change their password every time they want to edit their settings.
# we also check that they give their current password to change their password.
# Code copied from
# https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-edit-their-account-without-providing-a-password
def update
@member = Member.find(current_member.id)
successfully_updated = if needs_password?(@member, params)
@member.update_with_password(devise_parameter_sanitizer.sanitize(:account_update))
if needs_password?(@member, params)
successfully_updated = @member.update_with_password(devise_parameter_sanitizer.sanitize(:account_update))
else
# remove the virtual current_password attribute
# update_without_password doesn't know how to ignore it
params[:member].delete(:current_password)
@member.update_without_password(devise_parameter_sanitizer.sanitize(:account_update))
successfully_updated = @member.update_without_password(devise_parameter_sanitizer.sanitize(:account_update))
end
if successfully_updated
@@ -35,12 +34,11 @@ class RegistrationsController < Devise::RegistrationsController
else
render "edit"
end
end
end
# check if we need the current password to update fields
def needs_password?(member, params)
params[:member][:password].present? ||
params[:member][:password_confirmation].present?
params[:member][:password_confirmation].present?
end

View File

@@ -1,14 +1,9 @@
class RobotsController < ApplicationController
DEFAULT_FILENAME = 'config/robots.txt'.freeze
def robots
filename = if subdomain && subdomain != 'www'
"config/robots.#{ subdomain }.txt"
end
file_to_render = File.exists?(filename.to_s) ? filename : DEFAULT_FILENAME
filename = "config/robots.#{subdomain}.txt" if subdomain && subdomain != 'www'
file_to_render = File.exist?(filename.to_s) ? filename : DEFAULT_FILENAME
render file: file_to_render, layout: false, content_type: 'text/plain'
end

View File

@@ -92,6 +92,6 @@ class ScientificNamesController < ApplicationController
private
def scientific_name_params
params.require(:scientific_name).permit(:crop_id, :scientific_name, :creator_id)
params.require(:scientific_name).permit(:crop_id, :name, :creator_id)
end
end

View File

@@ -7,18 +7,18 @@ class SeedsController < ApplicationController
def index
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
if @owner
@seeds = @owner.seeds.includes(:owner, :crop).paginate(page: params[:page])
elsif @crop
@seeds = @crop.seeds.includes(:owner, :crop).paginate(page: params[:page])
else
@seeds = Seed.includes(:owner, :crop).paginate(page: params[:page])
end
@seeds = if @owner
@owner.seeds.includes(:owner, :crop).paginate(page: params[:page])
elsif @crop
@crop.seeds.includes(:owner, :crop).paginate(page: params[:page])
else
Seed.includes(:owner, :crop).paginate(page: params[:page])
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: @seeds }
format.rss { render layout: false } #index.rss.builder
format.rss { render layout: false } # index.rss.builder
format.csv do
if @owner
@filename = "Growstuff-#{@owner}-Seeds-#{Time.zone.now.to_s(:number)}.csv"
@@ -49,7 +49,7 @@ class SeedsController < ApplicationController
@seed = Seed.new
# using find_by_id here because it returns nil, unlike find
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
respond_to do |format|
format.html # new.html.erb

View File

@@ -1,5 +1,4 @@
module ApplicationHelper
def price_in_dollars(price)
return sprintf('%.2f', price / 100.0)
end
@@ -7,7 +6,7 @@ module ApplicationHelper
# 999 cents becomes 9.99 AUD -- for products/orders/etc
def price_with_currency(price)
return sprintf('%.2f %s', price / 100.0,
Growstuff::Application.config.currency)
Growstuff::Application.config.currency)
end
def parse_date(str)
@@ -26,20 +25,20 @@ module ApplicationHelper
def build_alert_classes(alert_type = :info)
classes = 'alert alert-dismissable '
case alert_type.to_sym
when :alert, :danger, :error, :validation_errors
classes += 'alert-danger'
when :warning, :todo
classes += 'alert-warning'
when :notice, :success
classes += 'alert-success'
when :info
classes += 'alert-info'
when :alert, :danger, :error, :validation_errors
classes += 'alert-danger'
when :warning, :todo
classes += 'alert-warning'
when :notice, :success
classes += 'alert-success'
when :info
classes += 'alert-info'
end
classes
end
# Produces a cache key for uniquely identifying cached fragments.
def cache_key_for(klass, identifier="all")
def cache_key_for(klass, identifier = "all")
count = klass.count
max_updated_at = klass.maximum(:updated_at).try(:utc).try(:to_s, :number)
"#{klass.name.downcase.pluralize}/#{identifier}-#{count}-#{max_updated_at}"
@@ -73,9 +72,9 @@ module ApplicationHelper
end
Gravatar.new(member.email).image_url({
size: size,
default: :identicon
})
size: size,
default: :identicon
})
end
# Returns a string with the quantity and the right pluralization for a

View File

@@ -1,6 +1,5 @@
module AutoSuggestHelper
def auto_suggest(resource, source, options={})
def auto_suggest(resource, source, options = {})
if options[:default] && !options[:default].new_record?
default = options[:default]
default_id = options[:default].try(:id)
@@ -13,10 +12,14 @@ module AutoSuggestHelper
source_path = Rails.application.routes.url_helpers.send("#{source}s_search_path")
%Q{
<input id="#{source}" class="auto-suggest #{options[:class]}" type="text" value="#{default}" data-source-url="#{source_path}", placeholder="e.g. lettuce">
<noscript class="text-warning">Warning: Javascript must be available to search and match crops</noscript>
<input id="#{resource}_#{source}_id" class="auto-suggest-id" type="hidden" name="#{resource}[#{source}_id]" value="#{default_id}">
<input id="#{source}" class="auto-suggest #{options[:class]}"
type="text" value="#{default}" data-source-url="#{source_path}",
placeholder="e.g. lettuce">
<noscript class="text-warning">
Warning: Javascript must be available to search and match crops
</noscript>
<input id="#{resource}_#{source}_id" class="auto-suggest-id"
type="hidden" name="#{resource}[#{source}_id]" value="#{default_id}">
}.html_safe
end
end

View File

@@ -2,7 +2,7 @@ module CropsHelper
def display_seed_availability(member, crop)
total_quantity = 0
seeds = member.seeds.select {|seed| seed.crop.name == crop.name }
seeds = member.seeds.select { |seed| seed.crop.name == crop.name }
seeds.each do |seed|
total_quantity = total_quantity + seed.quantity if seed.quantity

View File

@@ -1,10 +1,11 @@
module GardensHelper
def display_garden_description(garden)
if garden.description.nil?
"no description provided."
else
truncate(garden.description, length: 130, separator: ' ', omission: '... ') { link_to "Read more", garden_path(garden) }
truncate(garden.description, length: 130, separator: ' ', omission: '... ') do
link_to "Read more", garden_path(garden)
end
end
end

View File

@@ -1,5 +1,4 @@
module HarvestsHelper
def display_quantity(harvest)
human_quantity = display_human_quantity(harvest)
weight = display_weight(harvest)
@@ -16,10 +15,10 @@ module HarvestsHelper
end
def display_human_quantity(harvest)
if ! harvest.quantity.blank? && harvest.quantity > 0
if !harvest.quantity.blank? && harvest.quantity > 0
if harvest.unit == 'individual' # just the number
number_to_human(harvest.quantity, strip_insignificant_zeros: true)
elsif ! harvest.unit.blank? # pluralize anything else
elsif !harvest.unit.blank? # pluralize anything else
return pluralize(number_to_human(harvest.quantity, strip_insignificant_zeros: true), harvest.unit)
else
return "#{number_to_human(harvest.quantity, strip_insignificant_zeros: true)} #{harvest.unit}"
@@ -30,7 +29,7 @@ module HarvestsHelper
end
def display_weight(harvest)
if ! harvest.weight_quantity.blank? && harvest.weight_quantity > 0
if !harvest.weight_quantity.blank? && harvest.weight_quantity > 0
return "#{number_to_human(harvest.weight_quantity, strip_insignificant_zeros: true)} #{harvest.weight_unit}"
else
return nil
@@ -44,5 +43,4 @@ module HarvestsHelper
harvest.description
end
end
end

View File

@@ -1,11 +1,10 @@
module PlantingsHelper
def display_days_before_maturity(planting)
if planting.finished?
0
elsif !planting.finished_at.nil?
((p = planting.finished_at - DateTime.now).to_i) <= 0 ? 0 : p.to_i
elsif planting.days_before_maturity.nil?
elsif planting.planted_at.nil? || planting.days_before_maturity.nil?
"unknown"
else
((p = (planting.planted_at + planting.days_before_maturity) - DateTime.now).to_i <= 0) ? 0 : p.to_i
@@ -41,5 +40,4 @@ module PlantingsHelper
return "#{planting.owner}."
end
end
end

View File

@@ -3,7 +3,10 @@ class Notifier < ActionMailer::Base
default from: "Growstuff <noreply@growstuff.org>"
def verifier
raise "RAILS_SECRET_TOKEN environment variable not set - have you created config/application.yml?" unless ENV['RAILS_SECRET_TOKEN']
unless ENV['RAILS_SECRET_TOKEN']
raise "RAILS_SECRET_TOKEN environment variable"\
"not set - have you created config/application.yml?"
end
return ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN'])
end
@@ -30,7 +33,7 @@ class Notifier < ActionMailer::Base
if @member.send_planting_reminder
mail(to: @member.email,
subject: "What have you planted lately?")
subject: "What have you planted lately?")
end
end
@@ -48,5 +51,4 @@ class Notifier < ActionMailer::Base
@member, @crop = member, crop
mail(to: @member.email, subject: "#{crop.name.capitalize} has been rejected")
end
end

View File

@@ -108,7 +108,7 @@ class Ability
can :cancel, Order, member_id: member.id, completed_at: nil
can :destroy, Order, member_id: member.id, completed_at: nil
can :create, OrderItem
can :create, OrderItem
# for now, let's not let people mess with individual order items
cannot :read, OrderItem, order: { member_id: member.id }
cannot :update, OrderItem, order: { member_id: member.id, completed_at: nil }

View File

@@ -21,5 +21,4 @@ class Account < ActiveRecord::Base
return paid_until.to_s
end
end
end

View File

@@ -19,5 +19,4 @@ class Comment < ActiveRecord::Base
)
end
end
end

View File

@@ -1,4 +1,4 @@
class Crop < ActiveRecord::Base
class Crop < ActiveRecord::Base # rubocop:disable Metrics/ClassLength
extend FriendlyId
friendly_id :name, use: [:slugged, :finders]
@@ -19,13 +19,22 @@ class Crop < ActiveRecord::Base
belongs_to :parent, class_name: 'Crop'
has_many :varieties, class_name: 'Crop', foreign_key: 'parent_id'
has_and_belongs_to_many :posts
before_destroy {|crop| crop.posts.clear}
before_destroy { |crop| crop.posts.clear }
default_scope { order("lower(name) asc") }
scope :recent, -> { where(approval_status: "approved").reorder("created_at desc") }
scope :toplevel, -> { where(approval_status: "approved", parent_id: nil) }
scope :popular, -> { where(approval_status: "approved").reorder("plantings_count desc, lower(name) asc") }
scope :randomized, -> { where(approval_status: "approved").reorder('random()') } # ok on sqlite and psql, but not on mysql
scope :recent, lambda {
where(approval_status: "approved").reorder("created_at desc")
}
scope :toplevel, lambda {
where(approval_status: "approved", parent_id: nil)
}
scope :popular, lambda {
where(approval_status: "approved").reorder("plantings_count desc, lower(name) asc")
}
scope :randomized, lambda {
# ok on sqlite and psql, but not on mysql
where(approval_status: "approved").reorder('random()')
}
scope :pending_approval, -> { where(approval_status: "pending") }
scope :approved, -> { where(approval_status: "approved") }
scope :rejected, -> { where(approval_status: "rejected") }
@@ -33,7 +42,7 @@ class Crop < ActiveRecord::Base
## Wikipedia urls are only necessary when approving a crop
validates :en_wikipedia_url,
format: {
with: /\Ahttps?:\/\/en\.wikipedia\.org\/wiki/,
with: /\Ahttps?:\/\/en\.wikipedia\.org\/wiki\/[[:alnum:]%_]+\z/,
message: 'is not a valid English Wikipedia URL'
},
if: :approved?
@@ -57,30 +66,30 @@ class Crop < ActiveRecord::Base
# use Rails.env as a part of index name (eg. development_growstuff)
index_name [Rails.env, "growstuff"].join('_')
settings index: { number_of_shards: 1 },
analysis: {
tokenizer: {
gs_edgeNGram_tokenizer: {
type: "edgeNGram", # edgeNGram: NGram match from the start of a token
min_gram: 3,
max_gram: 10,
# token_chars: Elasticsearch will split on characters
# that dont belong to any of these classes
token_chars: [ "letter", "digit" ]
}
},
analyzer: {
gs_edgeNGram_analyzer: {
tokenizer: "gs_edgeNGram_tokenizer",
filter: ["lowercase"]
}
},
} do
analysis: {
tokenizer: {
gs_edgeNGram_tokenizer: {
type: "edgeNGram", # edgeNGram: NGram match from the start of a token
min_gram: 3,
max_gram: 10,
# token_chars: Elasticsearch will split on characters
# that dont belong to any of these classes
token_chars: ["letter", "digit"]
}
},
analyzer: {
gs_edgeNGram_analyzer: {
tokenizer: "gs_edgeNGram_tokenizer",
filter: ["lowercase"]
}
},
} do
mappings dynamic: 'false' do
indexes :id, type: 'long'
indexes :name, type: 'string', analyzer: 'gs_edgeNGram_analyzer'
indexes :approval_status, type: 'string'
indexes :scientific_names do
indexes :scientific_name,
indexes :name,
type: 'string',
analyzer: 'gs_edgeNGram_analyzer',
# Disabling field-length norm (norm). If the norm option is turned on(by default),
@@ -94,13 +103,13 @@ class Crop < ActiveRecord::Base
end
end
def as_indexed_json(options={})
def as_indexed_json(options = {})
self.as_json(
only: [:id, :name, :approval_status],
include: {
scientific_names: { only: :scientific_name },
scientific_names: { only: :name },
alternate_names: { only: :name }
})
})
end
# update the Elasticsearch index (only if we're using it in this
@@ -114,14 +123,12 @@ class Crop < ActiveRecord::Base
# End Elasticsearch section
def to_s
return name
name
end
def default_scientific_name
if scientific_names.size > 0
return scientific_names.first.scientific_name
else
return nil
scientific_names.first.name
end
end
@@ -134,7 +141,7 @@ class Crop < ActiveRecord::Base
# Crop has no photos? Look for the most recent harvest with a photo.
harvest_with_photo = Harvest.where(crop_id: id).joins(:photos).order('harvests.id DESC').limit(1).first
return harvest_with_photo.photos.first if harvest_with_photo
harvest_with_photo.photos.first if harvest_with_photo
end
# crop.sunniness
@@ -143,13 +150,7 @@ class Crop < ActiveRecord::Base
# key: sunniness (eg. 'sun')
# value: count of how many times it's been used by plantings
def sunniness
sunniness = Hash.new(0)
plantings.each do |p|
if !p.sunniness.blank?
sunniness[p.sunniness] += 1
end
end
return sunniness
count_uses_of_property 'sunniness'
end
# crop.planted_from
@@ -157,13 +158,7 @@ class Crop < ActiveRecord::Base
# key: propagation method (eg. 'seed')
# value: count of how many times it's been used by plantings
def planted_from
planted_from = Hash.new(0)
plantings.each do |p|
if !p.planted_from.blank?
planted_from[p.planted_from] += 1
end
end
return planted_from
count_uses_of_property 'planted_from'
end
# crop.popular_plant_parts
@@ -201,18 +196,18 @@ class Crop < ActiveRecord::Base
end
def approval_statuses
[ 'rejected', 'pending', 'approved' ]
['rejected', 'pending', 'approved']
end
def reasons_for_rejection
[ "already in database", "not edible", "not enough information", "other" ]
["already in database", "not edible", "not enough information", "other"]
end
# Crop.interesting
# returns a list of interesting crops, for use on the homepage etc
def Crop.interesting
howmany = 12 # max number to find
interesting_crops = []
howmany = 12 # max number to find
interesting_crops = []
Crop.includes(:photos).randomized.each do |c|
break if interesting_crops.size == howmany
next unless c.interesting?
@@ -221,16 +216,16 @@ class Crop < ActiveRecord::Base
return interesting_crops
end
# Crop.create_from_csv(row)
# used by db/seeds.rb and rake growstuff:import_crops
# CSV fields:
# - name (required)
# - en_wikipedia_url (required)
# - parent (name, optional)
# - scientific name (optional, can be picked up from parent if it has one)
# Crop.create_from_csv(row)
# used by db/seeds.rb and rake growstuff:import_crops
# CSV fields:
# - name (required)
# - en_wikipedia_url (required)
# - parent (name, optional)
# - scientific name (optional, can be picked up from parent if it has one)
def Crop.create_from_csv(row)
name,en_wikipedia_url,parent,scientific_names,alternate_names = row
name, en_wikipedia_url, parent, scientific_names, alternate_names = row
cropbot = Member.find_by_login_name('cropbot')
raise "cropbot account not found: run rake db:seed" unless cropbot
@@ -252,56 +247,37 @@ class Crop < ActiveRecord::Base
crop.add_scientific_names_from_csv(scientific_names)
crop.add_alternate_names_from_csv(alternate_names)
end
def add_scientific_names_from_csv(scientific_names)
names_to_add = []
if ! scientific_names.blank? # i.e. we actually passed something in, which isn't a given
if !scientific_names.blank? # i.e. we actually passed something in, which isn't a given
names_to_add = scientific_names.split(%r{,\s*})
elsif parent && parent.scientific_names.size > 0 # pick up from parent
names_to_add = parent.scientific_names.map{|s| s.scientific_name}
names_to_add = parent.scientific_names.map { |s| s.name }
else
logger.warn("Warning: no scientific name (not even on parent crop) for #{self}")
end
cropbot = Member.find_by_login_name('cropbot')
if names_to_add.size > 0
cropbot = Member.find_by_login_name('cropbot')
raise "cropbot account not found: run rake db:seed" unless cropbot
names_to_add.each do |n|
if self.scientific_names.exists?(scientific_name: n)
logger.warn("Warning: skipping duplicate scientific name #{n} for #{self}")
else
self.scientific_names.create(
scientific_name: n,
creator_id: cropbot.id
)
end
end
add_names_to_list(names_to_add, 'scientific')
end
end
def add_alternate_names_from_csv(alternate_names)
cropbot = Member.find_by_login_name('cropbot')
names_to_add = []
if ! alternate_names.blank? # i.e. we actually passed something in, which isn't a given
cropbot = Member.find_by_login_name('cropbot')
if !alternate_names.blank? # i.e. we actually passed something in, which isn't a given
raise "cropbot account not found: run rake db:seed" unless cropbot
names_to_add = alternate_names.split(%r{,\s*})
names_to_add.each do |n|
if self.alternate_names.exists?(name: n)
logger.warn("Warning: skipping duplicate alternate name #{n} for #{self}")
else
self.alternate_names.create(
name: n,
creator_id: cropbot.id
)
end
end
add_names_to_list(names_to_add, 'alternate')
end
end
@@ -317,21 +293,23 @@ class Crop < ActiveRecord::Base
def self.search(query)
if ENV['GROWSTUFF_ELASTICSEARCH'] == "true"
search_str = query.nil? ? "" : query.downcase
response = __elasticsearch__.search( {
# Finds documents which match any field, but uses the _score from
# the best field insead of adding up _score from each field.
query: {
multi_match: {
query: "#{search_str}",
analyzer: "standard",
fields: ["name", "scientific_names.scientific_name", "alternate_names.name"]
}
},
filter: {
term: {approval_status: "approved"}
},
size: 50
}
response = __elasticsearch__.search({
# Finds documents which match any field, but uses the _score from
# the best field insead of adding up _score from each field.
query: {
multi_match: {
query: "#{search_str}",
analyzer: "standard",
fields: ["name",
"scientific_names.scientific_name",
"alternate_names.name"]
}
},
filter: {
term: { approval_status: "approved" }
},
size: 50
}
)
return response.records.to_a
else
@@ -354,6 +332,41 @@ class Crop < ActiveRecord::Base
end
end
private
def add_names_to_list(names_to_add, list_name)
names_to_add.each do |n|
if name_already_exists(list_name, n)
logger.warn("Warning: skipping duplicate #{list_name} name #{n} for #{self}")
else
create_crop_in_list(list_name, n)
end
end
end
def create_crop_in_list(list_name, name)
cropbot = Member.find_by_login_name('cropbot')
create_hash = {
creator_id: "#{cropbot.id}",
name: name
}
self.send("#{list_name}_names").create(create_hash)
end
def name_already_exists(list_name, name)
self.send("#{list_name}_names").exists?(name: name)
end
def count_uses_of_property(col_name)
data = Hash.new(0)
plantings.each do |p|
if !p.send("#{col_name}").blank?
data[p.send("#{col_name}")] += 1
end
end
data
end
# Custom validations
def approval_status_cannot_be_changed_again
@@ -376,5 +389,4 @@ class Crop < ActiveRecord::Base
errors.add(:rejection_notes, "must be added if the reason for rejection is \"other\"")
end
end
end

View File

@@ -11,6 +11,4 @@ class Follow < ActiveRecord::Base
body: "#{self.follower.login_name} just followed you on #{ENV["GROWSTUFF_SITE_NAME"]}. "
)
end
end

View File

@@ -8,5 +8,4 @@ class Forum < ActiveRecord::Base
def to_s
return name
end
end

View File

@@ -9,14 +9,14 @@ class Garden < ActiveRecord::Base
has_and_belongs_to_many :photos
before_destroy do |garden|
photolist = garden.photos.to_a # save a temp copy of the photo list
garden.photos.clear # clear relationship b/w garden and photo
before_destroy do |garden|
photolist = garden.photos.to_a # save a temp copy of the photo list
garden.photos.clear # clear relationship b/w garden and photo
photolist.each do |photo|
photo.destroy_if_unused
end
end
photolist.each do |photo|
photo.destroy_if_unused
end
end
# set up geocoding
geocoded_by :location
@@ -33,7 +33,7 @@ class Garden < ActiveRecord::Base
validates :name,
format: {
with: /\S/
with: /\A\w+[\w ]+\z/
},
length: { maximum: 255 }
@@ -50,9 +50,9 @@ class Garden < ActiveRecord::Base
"acres" => "acre"
}
validates :area_unit, inclusion: { in: AREA_UNITS_VALUES.values,
message: "%{value} is not a valid area unit" },
allow_nil: true,
allow_blank: true
message: "%{value} is not a valid area unit" },
allow_nil: true,
allow_blank: true
after_validation :cleanup_area
@@ -76,7 +76,7 @@ class Garden < ActiveRecord::Base
seen_crops = []
plantings.each do |p|
if (! seen_crops.include?(p.crop))
if (!seen_crops.include?(p.crop))
unique_plantings.push(p)
seen_crops.push(p.crop)
end
@@ -103,5 +103,4 @@ class Garden < ActiveRecord::Base
def default_photo
return photos.first
end
end

View File

@@ -22,9 +22,9 @@ class Harvest < ActiveRecord::Base
validates :crop, approved: true
validates :crop, presence: {message: "must be present and exist in our database"}
validates :crop, presence: { message: "must be present and exist in our database" }
validates :plant_part, presence: {message: "must be present and exist in our database"}
validates :plant_part, presence: { message: "must be present and exist in our database" }
validates :quantity,
numericality: {
@@ -45,9 +45,9 @@ class Harvest < ActiveRecord::Base
"bushels" => "bushel"
}
validates :unit, inclusion: { in: UNITS_VALUES.values,
message: "%{value} is not a valid unit" },
allow_nil: true,
allow_blank: true
message: "%{value} is not a valid unit" },
allow_nil: true,
allow_blank: true
validates :weight_quantity,
numericality: { only_integer: false },
@@ -59,9 +59,9 @@ class Harvest < ActiveRecord::Base
"oz" => "oz"
}
validates :weight_unit, inclusion: { in: WEIGHT_UNITS_VALUES.values,
message: "%{value} is not a valid unit" },
allow_nil: true,
allow_blank: true
message: "%{value} is not a valid unit" },
allow_nil: true,
allow_blank: true
after_validation :cleanup_quantities
@@ -105,27 +105,26 @@ class Harvest < ActiveRecord::Base
string = ''
if self.quantity
string += "#{number_to_human(self.quantity.to_s, strip_insignificant_zeros: true)} "
if self.unit == 'individual'
string += 'individual '
else
if self.quantity == 1
string += "#{self.unit} of "
else
string += "#{self.unit.pluralize} of "
end
end
string += if self.unit == 'individual'
'individual '
elsif self.quantity == 1
"#{self.unit} of "
else
"#{self.unit.pluralize} of "
end
end
if self.unit != 'individual' # buckets of apricot*s*
string += "#{self.crop.name.pluralize}"
elsif self.quantity == 1
string += "#{self.crop.name}"
else
string += "#{self.crop.name.pluralize}"
end
string += if self.unit != 'individual' # buckets of apricot*s*
"#{self.crop.name.pluralize}"
elsif self.quantity == 1
"#{self.crop.name}"
else
"#{self.crop.name.pluralize}"
end
if self.weight_quantity
string += " weighing #{number_to_human(self.weight_quantity, strip_insignificant_zeros: true)} #{self.weight_unit}"
string += " weighing #{number_to_human(self.weight_quantity, strip_insignificant_zeros: true)}"\
" #{self.weight_unit}"
end
return string
@@ -134,5 +133,4 @@ class Harvest < ActiveRecord::Base
def default_photo
return photos.first || crop.default_photo
end
end

View File

@@ -4,7 +4,7 @@ class Member < ActiveRecord::Base
friendly_id :login_name, use: [:slugged, :finders]
has_many :posts, foreign_key: 'author_id'
has_many :posts, foreign_key: 'author_id'
has_many :comments, foreign_key: 'author_id'
has_many :forums, foreign_key: 'owner_id'
@@ -27,7 +27,6 @@ class Member < ActiveRecord::Base
has_many :photos
default_scope { order("lower(login_name) asc") }
scope :confirmed, -> { where('confirmed_at IS NOT NULL') }
scope :located, -> { where("location <> '' and latitude IS NOT NULL and longitude IS NOT NULL") }
@@ -45,8 +44,8 @@ class Member < ActiveRecord::Base
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :lockable, :timeoutable, :omniauthable
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :lockable, :timeoutable, :omniauthable
# set up geocoding
geocoded_by :location
@@ -59,7 +58,7 @@ class Member < ActiveRecord::Base
# Requires acceptance of the Terms of Service
validates_acceptance_of :tos_agreement, allow_nil: true,
accept: true
accept: true
validates :login_name,
length: {
@@ -80,12 +79,12 @@ class Member < ActiveRecord::Base
}
# Give each new member a default garden
after_create {|member| Garden.create(name: "Garden", owner_id: member.id) }
after_create { |member| Garden.create(name: "Garden", owner_id: member.id) }
# and an account record (for paid accounts etc)
# we use find_or_create to avoid accidentally creating a second one,
# which can happen sometimes especially with FactoryGirl associations
after_create {|member| Account.find_or_create_by(member_id: member.id) }
after_create { |member| Account.find_or_create_by(member_id: member.id) }
after_save :update_newsletter_subscription
@@ -159,21 +158,21 @@ class Member < ActiveRecord::Base
# Fetches a collection of photos from Flickr
# Returns a [[page of photos], total] pair.
# Total is needed for pagination.
def flickr_photos(page_num=1, set=nil)
def flickr_photos(page_num = 1, set = nil)
result = false
if set
result = flickr.photosets.getPhotos(
photoset_id: set,
page: page_num,
per_page: 30
)
else
result = flickr.people.getPhotos(
user_id: 'me',
page: page_num,
per_page: 30
)
end
result = if set
flickr.photosets.getPhotos(
photoset_id: set,
page: page_num,
per_page: 30
)
else
flickr.people.getPhotos(
user_id: 'me',
page: page_num,
per_page: 30
)
end
if result
return [result.photo, result.total]
else
@@ -213,7 +212,7 @@ class Member < ActiveRecord::Base
def Member.nearest_to(place)
nearby_members = []
if place
latitude, longitude = Geocoder.coordinates(place, params: {limit: 1})
latitude, longitude = Geocoder.coordinates(place, params: { limit: 1 })
if latitude && longitude
nearby_members = Member.located.sort_by { |x| x.distance_from([latitude, longitude]) }
end
@@ -235,24 +234,24 @@ class Member < ActiveRecord::Base
end
end
def newsletter_subscribe(testing=false)
def newsletter_subscribe(testing = false)
return true if (Rails.env.test? && !testing)
gb = Gibbon::API.new
res = gb.lists.subscribe({
id: Growstuff::Application.config.newsletter_list_id,
email: { email: email },
merge_vars: { login_name: login_name },
double_optin: false # they already confirmed their email with us
})
id: Growstuff::Application.config.newsletter_list_id,
email: { email: email },
merge_vars: { login_name: login_name },
double_optin: false # they already confirmed their email with us
})
end
def newsletter_unsubscribe(testing=false)
def newsletter_unsubscribe(testing = false)
return true if (Rails.env.test? && !testing)
gb = Gibbon::API.new
res = gb.lists.unsubscribe({
id: Growstuff::Application.config.newsletter_list_id,
email: { email: email }
})
id: Growstuff::Application.config.newsletter_list_id,
email: { email: email }
})
end
def already_following?(member)

View File

@@ -26,5 +26,4 @@ class Notification < ActiveRecord::Base
Notifier.notify(self).deliver_later
end
end
end

View File

@@ -27,10 +27,10 @@ class Order < ActiveRecord::Base
items = []
order_items.each do |i|
items.push({
name: i.product.name,
quantity: i.quantity,
amount: i.price
})
name: i.product.name,
quantity: i.quantity,
amount: i.price
})
end
return items
end
@@ -62,35 +62,34 @@ class Order < ActiveRecord::Base
# search orders (used by admin/orders)
# usage: Order.search({ :by => 'member', :for => 'Skud' })
# can search by: member, order_id, paypal_token, paypal_payer_id,
def Order.search(args={})
def Order.search(args = {})
if args[:for]
case args[:by]
when "member"
member = Member.find_by_login_name(args[:for])
if member
return member.orders
end
when "order_id"
order = Order.find_by_id(args[:for])
if order
return [order]
end
when "paypal_token"
order = Order.find_by_paypal_express_token(args[:for])
if order
return [order]
end
when "paypal_payer_id"
order = Order.find_by_paypal_express_payer_id(args[:for])
if order
return [order]
end
when "referral_code"
# coerce to uppercase
return Order.where(referral_code: args[:for].upcase)
when "member"
member = Member.find_by_login_name(args[:for])
if member
return member.orders
end
when "order_id"
order = Order.find_by_id(args[:for])
if order
return [order]
end
when "paypal_token"
order = Order.find_by_paypal_express_token(args[:for])
if order
return [order]
end
when "paypal_payer_id"
order = Order.find_by_paypal_express_payer_id(args[:for])
if order
return [order]
end
when "referral_code"
# coerce to uppercase
return Order.where(referral_code: args[:for].upcase)
end
end
return []
end
end

View File

@@ -34,11 +34,9 @@ class Photo < ActiveRecord::Base
fullsize_url: FlickRaw.url_z(info),
link_url: FlickRaw.url_photopage(info)
}
end
def set_flickr_metadata
self.update_attributes(flickr_metadata)
end
end

View File

@@ -20,5 +20,4 @@ class PlantPart < ActiveRecord::Base
def crops
return super.reorder('name')
end
end

View File

@@ -32,7 +32,7 @@ class Planting < ActiveRecord::Base
validates :crop, approved: true
validates :crop, presence: {message: "must be present and exist in our database"}
validates :crop, presence: { message: "must be present and exist in our database" }
validates :quantity,
numericality: {
@@ -42,9 +42,9 @@ class Planting < ActiveRecord::Base
SUNNINESS_VALUES = %w(sun semi-shade shade)
validates :sunniness, inclusion: { in: SUNNINESS_VALUES,
message: "%{value} is not a valid sunniness value" },
allow_nil: true,
allow_blank: true
message: "%{value} is not a valid sunniness value" },
allow_nil: true,
allow_blank: true
PLANTED_FROM_VALUES = [
'seed',
@@ -60,9 +60,9 @@ class Planting < ActiveRecord::Base
'layering'
]
validates :planted_from, inclusion: { in: PLANTED_FROM_VALUES,
message: "%{value} is not a valid planting method" },
allow_nil: true,
allow_blank: true
message: "%{value} is not a valid planting method" },
allow_nil: true,
allow_blank: true
validate :finished_must_be_after_planted
@@ -105,7 +105,7 @@ class Planting < ActiveRecord::Base
if differences.compact.empty?
nil
else
differences.compact.sum/differences.compact.size
differences.compact.sum / differences.compact.size
end
end
@@ -120,7 +120,7 @@ class Planting < ActiveRecord::Base
return 0 if current_date < planted_at
return 100 if days > days_before_maturity
percent = (days/days_before_maturity*100).to_i
percent = (days / days_before_maturity * 100).to_i
if percent >= 100
percent = 100
@@ -132,7 +132,7 @@ class Planting < ActiveRecord::Base
# return a list of interesting plantings, for the homepage etc.
# we can't do this via a scope (as far as we know) so sadly we have to
# do it this way.
def Planting.interesting(howmany=12, require_photo=true)
def Planting.interesting(howmany = 12, require_photo = true)
interesting_plantings = []
seen_owners = Hash.new(false) # keep track of which owners we've seen already

View File

@@ -5,14 +5,14 @@ class Post < ActiveRecord::Base
belongs_to :forum
has_many :comments, dependent: :destroy
has_and_belongs_to_many :crops
before_destroy {|post| post.crops.clear}
before_destroy { |post| post.crops.clear }
after_save :update_crops_posts_association
# also has_many notifications, but kinda meaningless to get at them
# from this direction, so we won't set up an association for now.
after_create do
recipients = []
sender = self.author.id
sender = self.author.id
self.body.scan(Haml::Filters::GrowstuffMarkdown::MEMBER_REGEX) do |m|
# find member case-insensitively and add to list of recipients
member = Member.where('lower(login_name) = ?', $1.downcase).first
@@ -24,7 +24,7 @@ class Post < ActiveRecord::Base
recipients << member if member && !recipients.include?(member)
end
# don't send notifications to yourself
recipients.map{ |r| r.id }.each do |recipient|
recipients.map { |r| r.id }.each do |recipient|
if recipient != sender
Notification.create(
recipient_id: recipient,
@@ -44,7 +44,6 @@ class Post < ActiveRecord::Base
},
length: { maximum: 255 }
def author_date_subject
# slugs are created before created_at is set
time = created_at || Time.zone.now
@@ -70,14 +69,15 @@ class Post < ActiveRecord::Base
end
private
def update_crops_posts_association
self.crops.destroy_all
# look for crops mentioned in the post. eg. [tomato](crop)
self.body.scan(Haml::Filters::GrowstuffMarkdown::CROP_REGEX) do |m|
# find crop case-insensitively
crop = Crop.where('lower(name) = ?', $1.downcase).first
# create association
self.crops << crop if crop && !self.crops.include?(crop)
end
def update_crops_posts_association
self.crops.destroy_all
# look for crops mentioned in the post. eg. [tomato](crop)
self.body.scan(Haml::Filters::GrowstuffMarkdown::CROP_REGEX) do |m|
# find crop case-insensitively
crop = Crop.where('lower(name) = ?', $1.downcase).first
# create association
self.crops << crop if crop && !self.crops.include?(crop)
end
end
end

View File

@@ -11,5 +11,4 @@ class Product < ActiveRecord::Base
def to_s
name
end
end

View File

@@ -9,7 +9,7 @@ class Seed < ActiveRecord::Base
validates :crop, approved: true
validates :crop, presence: {message: "must be present and exist in our database"}
validates :crop, presence: { message: "must be present and exist in our database" }
validates :quantity,
numericality: {
only_integer: true,
@@ -30,9 +30,10 @@ class Seed < ActiveRecord::Base
TRADABLE_TO_VALUES = %w(nowhere locally nationally internationally)
validates :tradable_to, inclusion: { in: TRADABLE_TO_VALUES,
message: "You may only trade seed nowhere, locally, nationally, or internationally" },
allow_nil: false,
allow_blank: false
message: "You may only trade seed nowhere, "\
"locally, nationally, or internationally" },
allow_nil: false,
allow_blank: false
ORGANIC_VALUES = [
'certified organic',
@@ -40,9 +41,10 @@ class Seed < ActiveRecord::Base
'conventional/non-organic',
'unknown']
validates :organic, inclusion: { in: ORGANIC_VALUES,
message: "You must say whether the seeds are organic or not, or that you don't know" },
allow_nil: false,
allow_blank: false
message: "You must say whether the seeds "\
"are organic or not, or that you don't know" },
allow_nil: false,
allow_blank: false
GMO_VALUES = [
'certified GMO-free',
@@ -50,15 +52,16 @@ class Seed < ActiveRecord::Base
'GMO',
'unknown']
validates :gmo, inclusion: { in: GMO_VALUES,
message: "You must say whether the seeds are genetically modified or not, or that you don't know" },
allow_nil: false,
allow_blank: false
message: "You must say whether the seeds are "\
"genetically modified or not, or that you don't know" },
allow_nil: false,
allow_blank: false
HEIRLOOM_VALUES = %w(heirloom hybrid unknown)
validates :heirloom, inclusion: { in: HEIRLOOM_VALUES,
message: "You must say whether the seeds are heirloom, hybrid, or unknown" },
allow_nil: false,
allow_blank: false
message: "You must say whether the seeds are heirloom, hybrid, or unknown" },
allow_nil: false,
allow_blank: false
def tradable?
if self.tradable_to == 'nowhere'
@@ -89,7 +92,6 @@ class Seed < ActiveRecord::Base
end
return interesting_seeds
end
def seed_slug

View File

@@ -55,7 +55,7 @@
.col-md-2
= label_tag :scientific_names, "Scientific name #{index+1}:", :class => 'control-label'
.col-md-8
= text_field_tag "sci_name[#{index+1}]", sci.scientific_name, :id => "sci_name[#{index+1}]", :class => 'form-control'
= text_field_tag "sci_name[#{index+1}]", sci.name, :id => "sci_name[#{index+1}]", :class => 'form-control'
%span.help-block Scientific name of crop.
.col-md-2

View File

@@ -2,7 +2,7 @@
%small
- if crop.scientific_names.size > 0
%i
= crop.scientific_names.first.scientific_name
= crop.scientific_names.first.name
%br/
Planted
= pluralize(crop.plantings.size, "time")

View File

@@ -6,7 +6,7 @@
%ul
- crop.scientific_names.each do |sn|
%li
= sn.scientific_name
= sn.name
- if can? :edit, sn
= link_to 'Edit', edit_scientific_name_path(sn), { :class => 'btn btn-default btn-xs' }
- if can? :destroy, sn

View File

@@ -8,7 +8,7 @@
= link_to crop.name, crop
- if crop.scientific_names.size > 0
.scientificname
= crop.scientific_names.first.scientific_name
= crop.scientific_names.first.name
.plantingcount
Planted
= pluralize(crop.plantings.size, "time")

View File

@@ -54,7 +54,7 @@
%td= link_to c.en_wikipedia_url, c.en_wikipedia_url
%td
- c.scientific_names.each do |s|
= link_to s.scientific_name, s
= link_to s.name, s
%br/
%td= c.requester.present? ? (link_to c.requester, c.requester) : "N/A"
- unless @approval_status == "pending"

View File

@@ -1,7 +1,7 @@
.panel.panel-success
.panel-heading
%h3.panel-title
= link_to "#{garden.owner.login_name}'s garden", garden.owner
= link_to "#{garden.owner.login_name}'s garden", garden
- if can? :edit, garden
%a.pull-right{:href => edit_garden_path(garden), :role => "button", :id => "edit_garden_glyphicon"}
%span.glyphicon.glyphicon-pencil{:title => "Edit"}

View File

@@ -17,9 +17,9 @@
.col-md-8
= collection_select(:scientific_name, :crop_id, Crop.all, :id, :name, { :selected => @scientific_name.crop_id || @crop.id }, :class => 'form-control')
.form-group
= f.label :scientific_name, :class => 'control-label col-md-2'
= f.label :name, :class => 'control-label col-md-2'
.col-md-8
= f.text_field :scientific_name, :class => 'form-control'
= f.text_field :name, :class => 'form-control'
.form-group
.form-actions.col-md-offset-2.col-md-8
= f.submit 'Save', :class => 'btn btn-primary'

View File

@@ -12,7 +12,7 @@
- @scientific_names.each do |scientific_name|
%tr
%td= link_to scientific_name.scientific_name, scientific_name
%td= link_to scientific_name.name, scientific_name
%td= scientific_name.crop_id
%td= link_to 'Show', scientific_name
%td

View File

@@ -2,7 +2,7 @@
- @scientific_name.crop.photos.each do |photo|
= tag("meta", property: "og:image", content: photo.fullsize_url)
= tag("meta", property: "og:title", content: @scientific_name.scientific_name)
= tag("meta", property: "og:title", content: @scientific_name.name)
= tag("meta", property: "og:type", content: "website")
= tag("meta", property: "og:url", content: request.original_url)
= tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME'])
@@ -13,7 +13,7 @@
%p
%b Scientific name:
= @scientific_name.scientific_name
= @scientific_name.name
%p
%b Crop:
= link_to @scientific_name.crop, @scientific_name.crop

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'

View File

@@ -16,7 +16,6 @@ images_dir = "app/assets/images"
# To disable debugging comments that display the original location of your selectors. Uncomment:
# line_comments = false
# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
preferred_syntax = :sass

View File

@@ -1,4 +1,4 @@
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
require ::File.expand_path('../config/environment', __FILE__)
run Growstuff::Application

View File

@@ -82,7 +82,6 @@ module Growstuff
g.javascripts false
end
# Growstuff-specific configuration variables
config.currency = 'AUD'
config.bot_email = "noreply@growstuff.org"
@@ -90,7 +89,7 @@ module Growstuff
config.user_agent_email = "info@growstuff.org"
Gibbon::API.api_key = ENV['GROWSTUFF_MAILCHIMP_APIKEY'] || 'notarealkey'
# API key can't be blank or tests fail
# API key can't be blank or tests fail
Gibbon::API.timeout = 10
Gibbon::API.throws_exceptions = false
config.newsletter_list_id = ENV['GROWSTUFF_MAILCHIMP_NEWSLETTER_ID']

View File

@@ -3,4 +3,4 @@ require 'rubygems'
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])

View File

@@ -1,16 +1,10 @@
development:
adapter: postgresql
database: growstuff_dev
host: localhost
user: postgres
password: postgres
test:
adapter: postgresql
database: growstuff_test
host: localhost
user: postgres
password: postgres
production:
adapter: postgresql

View File

@@ -48,11 +48,11 @@ Growstuff::Application.configure do
config.action_mailer.delivery_method = :letter_opener
config.action_mailer.smtp_settings = {
port: '587',
address: 'smtp.mandrillapp.com',
user_name: ENV['GROWSTUFF_MANDRILL_USERNAME'],
password: ENV['GROWSTUFF_MANDRILL_APIKEY'],
authentication: :login
port: '587',
address: 'smtp.mandrillapp.com',
user_name: ENV['GROWSTUFF_MANDRILL_USERNAME'],
password: ENV['GROWSTUFF_MANDRILL_APIKEY'],
authentication: :login
}
config.host = 'localhost:8080'

View File

@@ -70,12 +70,12 @@ Growstuff::Application.configure do
config.action_mailer.default_url_options = { host: 'growstuff.org' }
ActionMailer::Base.smtp_settings = {
port: ENV['SPARKPOST_SMTP_PORT'],
address: ENV['SPARKPOST_SMTP_HOST'],
user_name: ENV['SPARKPOST_SMTP_USERNAME'],
password: ENV['SPARKPOST_SMTP_PASSWORD'],
authentication: :login,
enable_starttls_auto: true
port: ENV['SPARKPOST_SMTP_PORT'],
address: ENV['SPARKPOST_SMTP_HOST'],
user_name: ENV['SPARKPOST_SMTP_USERNAME'],
password: ENV['SPARKPOST_SMTP_PASSWORD'],
authentication: :login,
enable_starttls_auto: true
}
ActionMailer::Base.delivery_method = :smtp

View File

@@ -72,12 +72,12 @@ Growstuff::Application.configure do
config.action_mailer.default_url_options = { host: 'staging.growstuff.org' }
ActionMailer::Base.smtp_settings = {
port: ENV['SPARKPOST_SMTP_PORT'],
address: ENV['SPARKPOST_SMTP_HOST'],
user_name: ENV['SPARKPOST_SMTP_USERNAME'],
password: ENV['SPARKPOST_SMTP_PASSWORD'],
authentication: :login,
enable_starttls_auto: true
port: ENV['SPARKPOST_SMTP_PORT'],
address: ENV['SPARKPOST_SMTP_HOST'],
user_name: ENV['SPARKPOST_SMTP_USERNAME'],
password: ENV['SPARKPOST_SMTP_PASSWORD'],
authentication: :login,
enable_starttls_auto: true
}
ActionMailer::Base.delivery_method = :smtp

View File

@@ -6,6 +6,10 @@ Growstuff::Application.configure do
# preloads Rails for running tests, you may have to set it to true.
config.eager_load = false
# Do not compile assets on-demand. On-demand compilation slows down the test
# suite and causes random test failures.
config.assets.compile = false
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
@@ -26,7 +30,7 @@ Growstuff::Application.configure do
config.action_dispatch.show_exceptions = true
# Disable request forgery protection in test environment
config.action_controller.allow_forgery_protection = false
config.action_controller.allow_forgery_protection = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
@@ -54,7 +58,6 @@ Growstuff::Application.configure do
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalBogusGateway.new
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalBogusGateway.new
end
end
Geocoder.configure(lookup: :test)
@@ -101,7 +104,7 @@ Geocoder::Lookup::Test.add_stub(
)
# Unknown location
Geocoder::Lookup::Test.add_stub( "Tatooine", [])
Geocoder::Lookup::Test.add_stub("Tatooine", [])
Capybara.configure do |config|
config.always_include_port = true
@@ -110,16 +113,16 @@ end
OmniAuth.config.test_mode = true
# Fake the omniauth
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
provider: 'facebook',
uid: '123545',
info: {
name: "John Testerson",
nickname: 'JohnnyT',
email: 'example.oauth.facebook@example.com',
image: 'http://findicons.com/files/icons/1072/face_avatars/300/i04.png'
},
credentials: {
token: "token",
secret: "donttell"
}
})
provider: 'facebook',
uid: '123545',
info: {
name: "John Testerson",
nickname: 'JohnnyT',
email: 'example.oauth.facebook@example.com',
image: 'http://findicons.com/files/icons/1072/face_avatars/300/i04.png'
},
credentials: {
token: "token",
secret: "donttell"
}
})

View File

@@ -9,7 +9,7 @@ ComfortableMexicanSofa.configure do |config|
# Module responsible for authentication. You can replace it with your own.
# It simply needs to have #authenticate method. See http_auth.rb for reference.
config.admin_auth = 'CmsDeviseAuth'
config.admin_auth = 'CmsDeviseAuth'
# Module responsible for authorization on admin side. It should have #authorize
# method that returns true or false based on params and loaded instance
@@ -91,7 +91,6 @@ ComfortableMexicanSofa.configure do |config|
# Reveal partials that can be overwritten in the admin area.
# Default is false.
# config.reveal_cms_partials = false
end
module CmsDeviseAuth

View File

@@ -1,3 +1,4 @@
# rubocop:disable Metrics/LineLength
# Use this hook to configure devise mailer, warden hooks and so forth.
# Many of these configuration options can be set straight in your model.
Devise.setup do |config|
@@ -25,7 +26,7 @@ Devise.setup do |config|
# session. If you need permissions, you should implement that in a before filter.
# You can also supply a hash where the value is a boolean determining whether
# or not authentication should be aborted when the value is not present.
config.authentication_keys = [ :login ]
config.authentication_keys = [:login]
# Configure parameters from the request object used for authentication. Each entry
# given should be a request method and it will automatically be passed to the
@@ -37,12 +38,12 @@ Devise.setup do |config|
# Configure which authentication keys should be case-insensitive.
# These keys will be downcased upon creating or modifying a user and when used
# to authenticate or find a user. Default is :email.
config.case_insensitive_keys = [ :email ]
config.case_insensitive_keys = [:email]
# Configure which authentication keys should have whitespace stripped.
# These keys will have whitespace before and after removed upon creating or
# modifying a user and when used to authenticate or find a user. Default is :email.
config.strip_whitespace_keys = [ :email, :login_name ]
config.strip_whitespace_keys = [:email, :login_name]
# Tell if authentication through request.params is enabled. True by default.
# It can be set to an array that will enable params authentication only for the
@@ -101,7 +102,7 @@ Devise.setup do |config|
config.reconfirmable = true
# Defines which key will be used when confirming an account
config.confirmation_keys = [ :login ]
config.confirmation_keys = [:login]
# ==> Configuration for :rememberable
# The time the user will be remembered without asking for credentials again.
@@ -157,7 +158,7 @@ Devise.setup do |config|
# ==> Configuration for :recoverable
#
# Defines which key will be used when recovering the password for an account
config.reset_password_keys = [ :login ]
config.reset_password_keys = [:login]
# Time interval you can reset your password with a reset password key.
# Don't put a too small interval or your users won't have the time to

View File

@@ -1,204 +1,175 @@
# Sample localization file for English. Add more files in this directory for other locales.
# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
---
en:
forms:
optional: "(Optional)"
unauthorized:
read:
notification: "You must be signed in to view notifications."
create:
planting: "Please sign in or sign up to plant something."
post: "Please sign in or sign up to post."
seed: "Please sign in or sign up to add seeds."
notification: "Please sign in to send a message."
all: "Please sign in or sign up to create a %{subject}."
manage:
all: "Not authorized to %{action} %{subject}."
layouts:
header:
skip: "Skip navigation menu"
browse_crops: &browse_crops "Browse Crops"
seeds: "Seeds"
plantings: "Plantings"
harvests: "Harvests"
community_map: "Community Map"
browse_members: "Browse Members"
posts: "Posts"
forums: &forums "Forums"
support_growstuff: "Support Growstuff"
profile: "Profile"
gardens: "Gardens"
account: "Account"
inbox_unread: "Inbox (%{unread_count})"
inbox: "Inbox"
crop_wrangling: "Crop Wrangling"
admin: "Admin"
your_stuff: "Your Stuff (%{unread_count})"
crops:
index:
title: *browse_crops
subtitle: "%{crops_size} total"
gardens:
form:
location_helper: "If you have a location set in your profile, it will be used when
you create a new garden."
seeds:
index:
title:
default: "Everyone's seeds"
crop_seeds: "Everyone's %{crop} seeds"
owner_seeds: "%{owner} seeds"
form:
trade_help: "Are you interested in trading or swapping seeds with other
%{site_name} members? If you
list your seeds as available for trade, other members can
contact you to request seeds. You can list any conditions or
other information in the description, above."
plantings:
index:
title:
default: "Everyone's plantings"
crop_plantings: "Everyone's %{crop} plantings"
owner_plantings: "%{owner} plantings"
form:
finish_helper: "A planting is finished when you've harvested all of the crop, or
it dies, or it's otherwise no longer growing in your garden."
photos:
show:
thing_by: "A %{thing} by %{owner}"
harvests:
index:
title:
default: "Everyone's harvests"
crop_harvests: "Everyone's %{crop} harvests"
owner_harvests: "%{owner} harvests"
places:
index:
title: "%{site_name} Community Map"
members:
index:
title: "%{site_name} members"
posts:
index:
title:
default: "Everyone's posts"
author_posts: "%{author} posts"
shop:
index:
title: "Shop"
forums:
index:
title: *forums
home:
blurb:
intro: "%{site_name} is a community of food gardeners. We're building an open source platform to help you learn about growing food, track what you plant and harvest, and swap seeds and produce with other gardeners near you."
perks: "Join now for your free garden journal, seed sharing, forums, and more."
sign_up: "Sign up"
already_html: "Or %{sign_in} if you already have an account"
sign_in_linktext: "sign in"
crops:
our_crops: "Some of our crops"
recently_planted: "Recently planted"
recently_added: "Recently added crops"
view_all: "View all crops"
discuss:
discussion: "Discussion"
forums: "Forums"
view_all: "View all posts"
members:
title: "Some of our members"
view_all: "View all members"
open:
open_source_title: "Open Source"
open_source_body_html: "%{site_name} is open source software, which means that we share this website's code for free with our community and the world. We believe that openness, sustainability, and social good go hand in hand. You can read more about %{why} or check out our code on %{github}."
why_linktext: "why Growstuff is open source"
github_linktext: "Github"
open_data_title: "Open Data and APIs"
open_data_body_html: "We're building a database of crops, planting advice, seed sources, and other information that anyone can use for free, under a %{creative_commons_link}. You can use this data for research, to build apps, or for any purpose at all. Read more about our %{wiki_link} and %{api_docs_link}."
creative_commons_linktext: "Creative Commons license"
api_docs_linktext: "API documentation"
get_involved_title: "Get Involved"
get_involved_body_html: "We believe in collaboration, and work closely with our members and the wider food-growing community. Our team includes volunteers from all walks of life and all skill levels. To get involved, visit %{talk_link} or find more information on the %{wiki_link}."
talk_linktext: "Growstuff Talk"
wiki_linktext: "Growstuff Wiki"
support_title: "Support Growstuff"
support_body_html: "Growstuff is independent, %{ad_free} and we have no outside investment. You can support our work by %{buy_account}."
ad_free_linktext: "ad-free"
buy_account_linktext: "buying a paid account"
seeds:
title: "Seeds available to trade"
owner: "Owner"
crop: "Crop"
description: "Description"
trade_to: "Will trade to"
from: "From location"
unspecified: "unspecified"
details: "Details"
view_all: "View all seeds"
stats:
message_html: "So far, %{member} have planted %{number_crops} %{number_plantings} in %{number_gardens}."
member_linktext: "%{count} members"
number_crops_linktext: "%{count} crops"
number_plantings_linktext: "%{count} times"
number_gardens_linktext: "%{count} gardens"
index:
welcome: "Welcome to %{site_name}, %{member_name}"
plant: "Plant"
harvest: "Harvest"
add_seeds: "Add seeds"
post: "Post"
edit_profile: "Edit profile"
activerecord:
models:
comment:
one: "comment"
other: "comments"
one: comment
other: comments
crop:
one: "crop"
other: "crops"
one: crop
other: crops
follow:
one: "follow"
other: "follows"
one: follow
other: follows
garden:
one: "garden"
other: "gardens"
one: garden
other: gardens
harvest:
one: "harvest"
other: "harvests"
one: harvest
other: harvests
member:
one: "member"
other: "members"
one: member
other: members
photo:
one: "photo"
other: "photos"
one: photo
other: photos
planting:
one: "planting"
other: "plantings"
one: planting
other: plantings
post:
one: "post"
other: "posts"
one: post
other: posts
seed:
one: "seed"
other: "seeds"
one: seed
other: seeds
crops:
index:
subtitle: "%{crops_size} total"
title: Browse Crops
forms:
optional: "(Optional)"
forums:
index:
title: Forums
gardens:
form:
location_helper: If you have a location set in your profile, it will be used when you create a new garden.
harvests:
index:
title:
crop_harvests: Everyone's %{crop} harvests
default: Everyone's harvests
owner_harvests: "%{owner} harvests"
home:
blurb:
already_html: Or %{sign_in} if you already have an account
intro: "%{site_name} is a community of food gardeners. We're building an open source platform to help you learn about growing food, track what you plant and harvest, and swap seeds and produce with other gardeners near you."
perks: Join now for your free garden journal, seed sharing, forums, and more.
sign_in_linktext: sign in
sign_up: Sign up
crops:
our_crops: Some of our crops
recently_added: Recently added crops
recently_planted: Recently planted
view_all: View all crops
discuss:
discussion: Discussion
forums: Forums
view_all: View all posts
index:
add_seeds: Add seeds
edit_profile: Edit profile
harvest: Harvest
plant: Plant
post: Post
welcome: Welcome to %{site_name}, %{member_name}
members:
title: Some of our members
view_all: View all members
open:
ad_free_linktext: ad-free
api_docs_linktext: API documentation
buy_account_linktext: buying a paid account
creative_commons_linktext: Creative Commons license
get_involved_body_html: We believe in collaboration, and work closely with our members and the wider food-growing community. Our team includes volunteers from all walks of life and all skill levels. To get involved, visit %{talk_link} or find more information on the %{wiki_link}.
get_involved_title: Get Involved
github_linktext: Github
open_data_body_html: We're building a database of crops, planting advice, seed sources, and other information that anyone can use for free, under a %{creative_commons_link}. You can use this data for research, to build apps, or for any purpose at all. Read more about our %{wiki_link} and %{api_docs_link}.
open_data_title: Open Data and APIs
open_source_body_html: "%{site_name} is open source software, which means that we share this website's code for free with our community and the world. We believe that openness, sustainability, and social good go hand in hand. You can read more about %{why} or check out our code on %{github}."
open_source_title: Open Source
support_body_html: Growstuff is independent, %{ad_free} and we have no outside investment. You can support our work by %{buy_account}.
support_title: Support Growstuff
talk_linktext: Growstuff Talk
why_linktext: why Growstuff is open source
wiki_linktext: Growstuff Wiki
seeds:
crop: Crop
description: Description
details: Details
from: From location
owner: Owner
title: Seeds available to trade
trade_to: Will trade to
unspecified: unspecified
view_all: View all seeds
stats:
member_linktext: "%{count} members"
message_html: So far, %{member} have planted %{number_crops} %{number_plantings} in %{number_gardens}.
number_crops_linktext: "%{count} crops"
number_gardens_linktext: "%{count} gardens"
number_plantings_linktext: "%{count} times"
layouts:
header:
account: Account
admin: Admin
browse_crops: Browse Crops
browse_members: Browse Members
community_map: Community Map
crop_wrangling: Crop Wrangling
forums: Forums
gardens: Gardens
harvests: Harvests
inbox: Inbox
inbox_unread: Inbox (%{unread_count})
plantings: Plantings
posts: Posts
profile: Profile
seeds: Seeds
skip: Skip navigation menu
support_growstuff: Support Growstuff
your_stuff: Your Stuff (%{unread_count})
members:
index:
title: "%{site_name} members"
photos:
show:
thing_by: A %{thing} by %{owner}
places:
index:
title: "%{site_name} Community Map"
plantings:
form:
finish_helper: A planting is finished when you've harvested all of the crop, or it dies, or it's otherwise no longer growing in your garden.
index:
title:
crop_plantings: Everyone's %{crop} plantings
default: Everyone's plantings
owner_plantings: "%{owner} plantings"
posts:
index:
title:
author_posts: "%{author} posts"
default: Everyone's posts
seeds:
form:
trade_help: Are you interested in trading or swapping seeds with other %{site_name} members? If you list your seeds as available for trade, other members can contact you to request seeds. You can list any conditions or other information in the description, above.
index:
title:
crop_seeds: Everyone's %{crop} seeds
default: Everyone's seeds
owner_seeds: "%{owner} seeds"
shop:
index:
title: Shop
unauthorized:
create:
all: Please sign in or sign up to create a %{subject}.
notification: Please sign in to send a message.
planting: Please sign in or sign up to plant something.
post: Please sign in or sign up to post.
seed: Please sign in or sign up to add seeds.
manage:
all: Not authorized to %{action} %{subject}.
read:
notification: You must be signed in to view notifications.

View File

@@ -1,10 +1,14 @@
Growstuff::Application.routes.draw do
Growstuff::Application.routes.draw do # rubocop:disable Metrics/BlockLength
get '/robots.txt' => 'robots#robots'
resources :plant_parts
devise_for :members, controllers: { registrations: "registrations", passwords: "passwords", sessions: "sessions", omniauth_callbacks: "omniauth_callbacks" }
devise_for :members, controllers: {
registrations: "registrations",
passwords: "passwords",
sessions: "sessions",
omniauth_callbacks: "omniauth_callbacks"
}
devise_scope :member do
get '/members/unsubscribe/:message' => 'members#unsubscribe', :as => 'unsubscribe_member'
end
@@ -53,7 +57,6 @@ Growstuff::Application.routes.draw do
get '/members/:login_name/follows' => 'members#view_follows', :as => 'member_follows'
get '/members/:login_name/followers' => 'members#view_followers', :as => 'member_followers'
get '/places' => 'places#index'
get '/places/search' => 'places#search', :as => 'search_places'
get '/places/:place' => 'places#show', :as => 'place'
@@ -86,7 +89,6 @@ Growstuff::Application.routes.draw do
get '/.well-known/acme-challenge/:id' => 'pages#letsencrypt'
# CMS stuff -- must remain LAST
# CMS stuff -- must remain LAST
comfy_route :cms, path: '/', sitemap: false
end

View File

@@ -4,7 +4,6 @@ timeout 30
preload_app true
before_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
Process.kill 'QUIT', Process.pid
@@ -15,7 +14,6 @@ before_fork do |server, worker|
end
after_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT'
end

View File

@@ -33,7 +33,6 @@ class DeviseCreateUsers < ActiveRecord::Migration
## Token authenticatable
# t.string :authentication_token
t.timestamps null: true
end

View File

@@ -1,5 +1,5 @@
class AddCreationIndexToUpdates < ActiveRecord::Migration
def change
add_index :updates, [:created_at, :user_id]
add_index :updates, [:created_at, :user_id]
end
end

View File

@@ -2,5 +2,4 @@ class RenameAccountDetailToAccount < ActiveRecord::Migration
def change
rename_table :account_details, :accounts
end
end

View File

@@ -3,6 +3,7 @@ class ChangeFlickrPhotoIdToString < ActiveRecord::Migration
remove_column :photos, :flickr_photo_id
add_column :photos, :flickr_photo_id, :string
end
def down
# Postgres doesn't allow you to cast strings to integers
# Hence there's no way of rolling back this migration without losing

View File

@@ -1,11 +1,11 @@
class CreateCms < ActiveRecord::Migration
def self.up
def self.up # rubocop:disable Metrics/MethodLength
text_limit = case ActiveRecord::Base.connection.adapter_name
when 'PostgreSQL'
{ }
else
{ limit: 16777215 }
end
when 'PostgreSQL'
{}
else
{ limit: 16777215 }
end
# -- Sites --------------------------------------------------------------
create_table :comfy_cms_sites do |t|
@@ -42,7 +42,7 @@ class CreateCms < ActiveRecord::Migration
t.integer :layout_id
t.integer :parent_id
t.integer :target_page_id
t.string :label, null: false
t.string :label, null: false
t.string :slug
t.string :full_path, null: false
t.text :content_cache, text_limit
@@ -80,7 +80,7 @@ class CreateCms < ActiveRecord::Migration
# -- Files --------------------------------------------------------------
create_table :comfy_cms_files do |t|
t.integer :site_id, null: false
t.integer :site_id, null: false
t.integer :block_id
t.string :label, null: false
t.string :file_file_name, null: false
@@ -111,7 +111,8 @@ class CreateCms < ActiveRecord::Migration
t.string :label, null: false
t.string :categorized_type, null: false
end
add_index :comfy_cms_categories, [:site_id, :categorized_type, :label], unique: true,
add_index :comfy_cms_categories, [:site_id, :categorized_type, :label],
unique: true,
name: 'index_cms_categories_on_site_id_and_cat_type_and_label'
create_table :comfy_cms_categorizations, force: true do |t|
@@ -119,7 +120,8 @@ class CreateCms < ActiveRecord::Migration
t.string :categorized_type, null: false
t.integer :categorized_id, null: false
end
add_index :comfy_cms_categorizations, [:category_id, :categorized_type, :categorized_id], unique: true,
add_index :comfy_cms_categorizations, [:category_id, :categorized_type, :categorized_id],
unique: true,
name: 'index_cms_categorizations_on_cat_id_and_catd_type_and_catd_id'
end

View File

@@ -0,0 +1,9 @@
class RenameScientificName < ActiveRecord::Migration
def self.up
rename_column :scientific_names, :scientific_name, :name
end
def self.down
rename_column :scientific_names, :name, :scientific_name
end
end

View File

@@ -11,12 +11,12 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150824145414) do
ActiveRecord::Schema.define(version: 20161129021533) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "account_types", force: true do |t|
create_table "account_types", force: :cascade do |t|
t.string "name", null: false
t.boolean "is_paid"
t.boolean "is_permanent_paid"
@@ -24,7 +24,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
t.datetime "updated_at"
end
create_table "accounts", force: true do |t|
create_table "accounts", force: :cascade do |t|
t.integer "member_id", null: false
t.integer "account_type_id"
t.datetime "paid_until"
@@ -32,7 +32,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
t.datetime "updated_at"
end
create_table "alternate_names", force: true do |t|
create_table "alternate_names", force: :cascade do |t|
t.string "name", null: false
t.integer "crop_id", null: false
t.integer "creator_id", null: false
@@ -40,7 +40,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
t.datetime "updated_at"
end
create_table "authentications", force: true do |t|
create_table "authentications", force: :cascade do |t|
t.integer "member_id", null: false
t.string "provider", null: false
t.string "uid"
@@ -53,7 +53,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "authentications", ["member_id"], name: "index_authentications_on_member_id", using: :btree
create_table "comfy_cms_blocks", force: true do |t|
create_table "comfy_cms_blocks", force: :cascade do |t|
t.string "identifier", null: false
t.text "content"
t.integer "blockable_id"
@@ -65,7 +65,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "comfy_cms_blocks", ["blockable_id", "blockable_type"], name: "index_comfy_cms_blocks_on_blockable_id_and_blockable_type", using: :btree
add_index "comfy_cms_blocks", ["identifier"], name: "index_comfy_cms_blocks_on_identifier", using: :btree
create_table "comfy_cms_categories", force: true do |t|
create_table "comfy_cms_categories", force: :cascade do |t|
t.integer "site_id", null: false
t.string "label", null: false
t.string "categorized_type", null: false
@@ -73,7 +73,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "comfy_cms_categories", ["site_id", "categorized_type", "label"], name: "index_cms_categories_on_site_id_and_cat_type_and_label", unique: true, using: :btree
create_table "comfy_cms_categorizations", force: true do |t|
create_table "comfy_cms_categorizations", force: :cascade do |t|
t.integer "category_id", null: false
t.string "categorized_type", null: false
t.integer "categorized_id", null: false
@@ -81,7 +81,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "comfy_cms_categorizations", ["category_id", "categorized_type", "categorized_id"], name: "index_cms_categorizations_on_cat_id_and_catd_type_and_catd_id", unique: true, using: :btree
create_table "comfy_cms_files", force: true do |t|
create_table "comfy_cms_files", force: :cascade do |t|
t.integer "site_id", null: false
t.integer "block_id"
t.string "label", null: false
@@ -99,7 +99,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "comfy_cms_files", ["site_id", "label"], name: "index_comfy_cms_files_on_site_id_and_label", using: :btree
add_index "comfy_cms_files", ["site_id", "position"], name: "index_comfy_cms_files_on_site_id_and_position", using: :btree
create_table "comfy_cms_layouts", force: true do |t|
create_table "comfy_cms_layouts", force: :cascade do |t|
t.integer "site_id", null: false
t.integer "parent_id"
t.string "app_layout"
@@ -117,7 +117,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "comfy_cms_layouts", ["parent_id", "position"], name: "index_comfy_cms_layouts_on_parent_id_and_position", using: :btree
add_index "comfy_cms_layouts", ["site_id", "identifier"], name: "index_comfy_cms_layouts_on_site_id_and_identifier", unique: true, using: :btree
create_table "comfy_cms_pages", force: true do |t|
create_table "comfy_cms_pages", force: :cascade do |t|
t.integer "site_id", null: false
t.integer "layout_id"
t.integer "parent_id"
@@ -137,7 +137,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "comfy_cms_pages", ["parent_id", "position"], name: "index_comfy_cms_pages_on_parent_id_and_position", using: :btree
add_index "comfy_cms_pages", ["site_id", "full_path"], name: "index_comfy_cms_pages_on_site_id_and_full_path", using: :btree
create_table "comfy_cms_revisions", force: true do |t|
create_table "comfy_cms_revisions", force: :cascade do |t|
t.string "record_type", null: false
t.integer "record_id", null: false
t.text "data"
@@ -146,7 +146,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "comfy_cms_revisions", ["record_type", "record_id", "created_at"], name: "index_cms_revisions_on_rtype_and_rid_and_created_at", using: :btree
create_table "comfy_cms_sites", force: true do |t|
create_table "comfy_cms_sites", force: :cascade do |t|
t.string "label", null: false
t.string "identifier", null: false
t.string "hostname", null: false
@@ -158,7 +158,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "comfy_cms_sites", ["hostname"], name: "index_comfy_cms_sites_on_hostname", using: :btree
add_index "comfy_cms_sites", ["is_mirrored"], name: "index_comfy_cms_sites_on_is_mirrored", using: :btree
create_table "comfy_cms_snippets", force: true do |t|
create_table "comfy_cms_snippets", force: :cascade do |t|
t.integer "site_id", null: false
t.string "label", null: false
t.string "identifier", null: false
@@ -172,7 +172,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "comfy_cms_snippets", ["site_id", "identifier"], name: "index_comfy_cms_snippets_on_site_id_and_identifier", unique: true, using: :btree
add_index "comfy_cms_snippets", ["site_id", "position"], name: "index_comfy_cms_snippets_on_site_id_and_position", using: :btree
create_table "comments", force: true do |t|
create_table "comments", force: :cascade do |t|
t.integer "post_id", null: false
t.integer "author_id", null: false
t.text "body", null: false
@@ -180,7 +180,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
t.datetime "updated_at"
end
create_table "crops", force: true do |t|
create_table "crops", force: :cascade do |t|
t.string "name", null: false
t.string "en_wikipedia_url"
t.datetime "created_at"
@@ -200,7 +200,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "crops", ["requester_id"], name: "index_crops_on_requester_id", using: :btree
add_index "crops", ["slug"], name: "index_crops_on_slug", unique: true, using: :btree
create_table "crops_posts", id: false, force: true do |t|
create_table "crops_posts", id: false, force: :cascade do |t|
t.integer "crop_id"
t.integer "post_id"
end
@@ -208,14 +208,14 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "crops_posts", ["crop_id", "post_id"], name: "index_crops_posts_on_crop_id_and_post_id", using: :btree
add_index "crops_posts", ["crop_id"], name: "index_crops_posts_on_crop_id", using: :btree
create_table "follows", force: true do |t|
create_table "follows", force: :cascade do |t|
t.integer "follower_id"
t.integer "followed_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "forums", force: true do |t|
create_table "forums", force: :cascade do |t|
t.string "name", null: false
t.text "description", null: false
t.integer "owner_id", null: false
@@ -226,7 +226,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "forums", ["slug"], name: "index_forums_on_slug", unique: true, using: :btree
create_table "gardens", force: true do |t|
create_table "gardens", force: :cascade do |t|
t.string "name", null: false
t.integer "owner_id"
t.string "slug", null: false
@@ -244,14 +244,14 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "gardens", ["owner_id"], name: "index_gardens_on_owner_id", using: :btree
add_index "gardens", ["slug"], name: "index_gardens_on_slug", unique: true, using: :btree
create_table "gardens_photos", id: false, force: true do |t|
create_table "gardens_photos", id: false, force: :cascade do |t|
t.integer "photo_id"
t.integer "garden_id"
end
add_index "gardens_photos", ["garden_id", "photo_id"], name: "index_gardens_photos_on_garden_id_and_photo_id", using: :btree
create_table "harvests", force: true do |t|
create_table "harvests", force: :cascade do |t|
t.integer "crop_id", null: false
t.integer "owner_id", null: false
t.date "harvested_at"
@@ -267,14 +267,14 @@ ActiveRecord::Schema.define(version: 20150824145414) do
t.float "si_weight"
end
create_table "harvests_photos", id: false, force: true do |t|
create_table "harvests_photos", id: false, force: :cascade do |t|
t.integer "photo_id"
t.integer "harvest_id"
end
add_index "harvests_photos", ["harvest_id", "photo_id"], name: "index_harvests_photos_on_harvest_id_and_photo_id", using: :btree
create_table "members", force: true do |t|
create_table "members", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
@@ -315,12 +315,12 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "members", ["slug"], name: "index_members_on_slug", unique: true, using: :btree
add_index "members", ["unlock_token"], name: "index_members_on_unlock_token", unique: true, using: :btree
create_table "members_roles", id: false, force: true do |t|
create_table "members_roles", id: false, force: :cascade do |t|
t.integer "member_id"
t.integer "role_id"
end
create_table "notifications", force: true do |t|
create_table "notifications", force: :cascade do |t|
t.integer "sender_id"
t.integer "recipient_id", null: false
t.string "subject"
@@ -331,7 +331,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
t.datetime "updated_at"
end
create_table "order_items", force: true do |t|
create_table "order_items", force: :cascade do |t|
t.integer "order_id"
t.integer "product_id"
t.integer "price"
@@ -340,7 +340,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
t.datetime "updated_at"
end
create_table "orders", force: true do |t|
create_table "orders", force: :cascade do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "completed_at"
@@ -350,12 +350,12 @@ ActiveRecord::Schema.define(version: 20150824145414) do
t.string "referral_code"
end
create_table "orders_products", id: false, force: true do |t|
create_table "orders_products", id: false, force: :cascade do |t|
t.integer "order_id"
t.integer "product_id"
end
create_table "photos", force: true do |t|
create_table "photos", force: :cascade do |t|
t.integer "owner_id", null: false
t.string "thumbnail_url", null: false
t.string "fullsize_url", null: false
@@ -368,19 +368,19 @@ ActiveRecord::Schema.define(version: 20150824145414) do
t.string "flickr_photo_id"
end
create_table "photos_plantings", id: false, force: true do |t|
create_table "photos_plantings", id: false, force: :cascade do |t|
t.integer "photo_id"
t.integer "planting_id"
end
create_table "plant_parts", force: true do |t|
create_table "plant_parts", force: :cascade do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.string "slug"
end
create_table "plantings", force: true do |t|
create_table "plantings", force: :cascade do |t|
t.integer "garden_id", null: false
t.integer "crop_id", null: false
t.date "planted_at"
@@ -399,7 +399,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "plantings", ["slug"], name: "index_plantings_on_slug", unique: true, using: :btree
create_table "posts", force: true do |t|
create_table "posts", force: :cascade do |t|
t.integer "author_id", null: false
t.string "subject", null: false
t.text "body", null: false
@@ -412,7 +412,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "posts", ["created_at", "author_id"], name: "index_posts_on_created_at_and_author_id", using: :btree
add_index "posts", ["slug"], name: "index_posts_on_slug", unique: true, using: :btree
create_table "products", force: true do |t|
create_table "products", force: :cascade do |t|
t.string "name", null: false
t.text "description", null: false
t.integer "min_price", null: false
@@ -423,7 +423,7 @@ ActiveRecord::Schema.define(version: 20150824145414) do
t.integer "recommended_price"
end
create_table "roles", force: true do |t|
create_table "roles", force: :cascade do |t|
t.string "name", null: false
t.text "description"
t.datetime "created_at"
@@ -433,15 +433,15 @@ ActiveRecord::Schema.define(version: 20150824145414) do
add_index "roles", ["slug"], name: "index_roles_on_slug", unique: true, using: :btree
create_table "scientific_names", force: true do |t|
t.string "scientific_name", null: false
t.integer "crop_id", null: false
create_table "scientific_names", force: :cascade do |t|
t.string "name", null: false
t.integer "crop_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "creator_id"
end
create_table "seeds", force: true do |t|
create_table "seeds", force: :cascade do |t|
t.integer "owner_id", null: false
t.integer "crop_id", null: false
t.text "description"

View File

@@ -69,16 +69,15 @@ def load_test_users
puts "Warning: unable to open suburbs.csv"
end
# rake parameter (eg. 'rake db:seed member_size=10')
member_size = ENV['member_size'] ? ENV['member_size'].to_i : 3
(1..member_size).each do |i|
@user = Member.new(
login_name: "test#{i}",
email: "test#{i}@example.com",
password: "password#{i}",
tos_agreement: true
login_name: "test#{i}",
email: "test#{i}@example.com",
password: "password#{i}",
tos_agreement: true
)
@user.skip_confirmation!
@user.save!
@@ -88,7 +87,7 @@ def load_test_users
suburb_file.pos = 0 if suburb_file.eof?
row = CSV.parse(suburb_file.readline)
suburb,country,state,latitude,longitude = row[0]
suburb, country, state, latitude, longitude = row[0]
# Using 'update_column' method instead of 'update' so that
# it avoids accessing Geocoding service for faster processing
@user.gardens.first.update_columns(location: suburb, latitude: latitude, longitude: longitude)
@@ -199,7 +198,7 @@ def load_plant_parts
end
def select_random_item(array)
array[rand(0..array.size-1) % array.size]
array[rand(0..array.size - 1) % array.size]
end
load_data

View File

@@ -1,5 +1,4 @@
class Growstuff::OauthSignupAction
#
# Inspects the omniauth information
# and determines if we have an existing member
@@ -12,14 +11,14 @@ class Growstuff::OauthSignupAction
def find_or_create_from_authorization(auth)
member ||= Member.where(email: auth.info.email).first_or_create do |m|
m.email = auth.info.email
m.password = Devise.friendly_token[0,20]
m.password = Devise.friendly_token[0, 20]
# First, try the nickname or friendly generate from the email
m.login_name = auth.info.nickname || auth.info.email.split("@").first.gsub(/[^A-Za-z]+/, '_').underscore
# Do we have a collision with an existing account? Generate a 20 character long random name
# so the user can update it later
m.login_name = Devise.friendly_token[0,20] if Member.where(login_name: m.login_name).any?
m.login_name = Devise.friendly_token[0, 20] if Member.where(login_name: m.login_name).any?
m.preferred_avatar_uri = auth.info.image # assuming the user model has an image
m.skip_confirmation!

View File

@@ -8,7 +8,7 @@ module Geocodable
def geocode
unless self.location.blank?
self.latitude, self.longitude =
Geocoder.coordinates(location, params: {limit: 1})
Geocoder.coordinates(location, params: { limit: 1 })
end
end
@@ -18,5 +18,4 @@ module Geocodable
self.longitude = nil
end
end
end

View File

@@ -9,8 +9,7 @@ module Haml::Filters
end
end
# Register it as the handler for the :escaped_markdown HAML command.
# The automatic system gives us :escapedmarkdown, which is ugly.
defined['escaped_markdown'] = EscapedMarkdown
# Register it as the handler for the :escaped_markdown HAML command.
# The automatic system gives us :escapedmarkdown, which is ugly.
defined['escaped_markdown'] = EscapedMarkdown
end

View File

@@ -9,7 +9,6 @@ module Haml::Filters
include Haml::Filters::Base
def render(text)
# turn [tomato](crop) into [tomato](http://growstuff.org/crops/tomato)
expanded = text.gsub(CROP_REGEX) do |m|
crop_str = $1
@@ -52,12 +51,10 @@ module Haml::Filters
expanded = expanded.gsub(MEMBER_ESCAPE_AT_REGEX, "")
return BlueCloth.new(expanded).to_html
end
end
# Register it as the handler for the :growstuff_markdown HAML command.
# The automatic system gives us :growstuffmarkdown, which is ugly.
defined['growstuff_markdown'] = GrowstuffMarkdown
# Register it as the handler for the :growstuff_markdown HAML command.
# The automatic system gives us :growstuffmarkdown, which is ugly.
defined['growstuff_markdown'] = GrowstuffMarkdown
end

View File

@@ -1,5 +1,4 @@
namespace :growstuff do
desc "Add an admin user, by name"
# usage: rake growstuff:admin_user name=skud
@@ -38,7 +37,6 @@ namespace :growstuff do
end
Rails.cache.delete('full_crop_hierarchy')
puts "Finished loading crops"
end
desc "Send planting reminder email"
@@ -73,10 +71,8 @@ namespace :growstuff do
desc "One-off tasks needed at various times and kept for posterity"
namespace :oneoff do
desc "May 2013: replace any empty notification subjects with (no subject)"
task empty_subjects: :environment do
# this is inefficient as it checks every Notification, but the
# site is small and there aren't many of them, so it shouldn't matter
# for this one-off script.
@@ -88,7 +84,6 @@ namespace :growstuff do
desc "May 2013: replace any empty garden names with Garden"
task empty_garden_names: :environment do
# this is inefficient as it checks every Garden, but the
# site is small and there aren't many of them, so it shouldn't matter
# for this one-off script.
@@ -100,7 +95,6 @@ namespace :growstuff do
end
end
desc "June 2013: create account types and products."
task setup_shop: :environment do
puts "Adding account types..."
@@ -128,14 +122,18 @@ namespace :growstuff do
puts "Adding products..."
Product.find_or_create_by(
name: "Annual subscription",
description: "An annual subscription gives you access to paid account features for one year. Does not auto-renew.",
description: "An annual subscription gives you access "\
"to paid account features for one year. Does not auto-renew.",
min_price: 3000,
account_type_id: @paid_account.id,
paid_months: 12
)
Product.find_or_create_by(
name: "Seed account",
description: "A seed account helps Growstuff grow in its early days. It gives you all the features of a paid account, in perpetuity. This account type never expires.",
description: "A seed account helps Growstuff grow in its "\
"early days. It gives you all the features of "\
"a paid account, in perpetuity. This account "\
"type never expires.",
min_price: 15000,
account_type_id: @seed_account.id,
)
@@ -159,7 +157,6 @@ namespace :growstuff do
desc "June 2013: replace nil account_types with free accounts"
task nil_account_type: :environment do
free = AccountType.find_by_name("Free")
raise "Free account type not found: run rake growstuff:oneoff:setup_shop"\
unless free
@@ -173,7 +170,6 @@ namespace :growstuff do
desc "July 2013: replace nil seed.tradable_to with nowhere"
task tradable_to_nowhere: :environment do
Seed.all.each do |s|
unless s.tradable_to
s.tradable_to = 'nowhere'
@@ -184,7 +180,6 @@ namespace :growstuff do
desc "August 2013: set up plantings_count cache on crop"
task reset_crop_plantings_count: :environment do
Crop.find_each do |c|
Crop.reset_counters c.id, :plantings
end
@@ -192,7 +187,6 @@ namespace :growstuff do
desc "August 2013: set default creator on existing crops"
task set_default_crop_creator: :environment do
cropbot = Member.find_by_login_name("cropbot")
raise "cropbot not found: create cropbot member on site or run rake db:seed" unless cropbot
cropbot.account.account_type = AccountType.find_by_name("Staff") # set this just because it's nice
@@ -209,7 +203,6 @@ namespace :growstuff do
sn.save
end
end
end
desc "August 2013: set planting owner"
@@ -335,5 +328,4 @@ namespace :growstuff do
Crop.import
end
end # end oneoff section
end

View File

@@ -1,5 +1,5 @@
desc "Install git hooks"
task :hooks do
FileUtils.symlink '../../script/pre-commit.sh', '.git/hooks/pre-commit',
force: true
FileUtils.symlink '../../script/pre-commit.sh', '.git/hooks/pre-commit',
force: true
end

View File

@@ -2,7 +2,7 @@ require 'rake'
begin
require 'rspec/core/rake_task'
task(:spec).clear
RSpec::Core::RakeTask.new(spec: 'db:test:prepare') do |t|
RSpec::Core::RakeTask.new(spec: ['db:create', 'db:test:prepare']) do |t|
t.verbose = false
end
rescue LoadError

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
# This command will automatically be run when you run "rails"
# with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'

View File

@@ -10,19 +10,13 @@
## If you submit a pull request containing new view or controller tests, it will not be
## merged.
require 'rails_helper'
describe AccountTypesController do
# This automatically creates a "Free" account type
login_member(:admin_member)
def valid_attributes
{ "name" => "MyString" }
end
end

View File

@@ -10,14 +10,9 @@
## If you submit a pull request containing new view or controller tests, it will not be
## merged.
require 'rails_helper'
describe AccountsController do
login_member(:admin_member)
def valid_attributes
@@ -32,5 +27,4 @@ describe AccountsController do
member = FactoryGirl.create(:member)
return member.account
end
end

View File

@@ -10,29 +10,22 @@
## If you submit a pull request containing new view or controller tests, it will not be
## merged.
require 'rails_helper'
describe Admin::OrdersController do
login_member(:admin_member)
describe "GET search" do
it "assigns @orders" do
order = FactoryGirl.create(:order)
get :search, {search_by: 'order_id', search_text: order.id}
get :search, { search_by: 'order_id', search_text: order.id }
assigns(:orders).should eq([order])
end
it "sets an error message if nothing found" do
order = FactoryGirl.create(:order)
get :search, {search_by: 'order_id', search_text: 'foo'}
get :search, { search_by: 'order_id', search_text: 'foo' }
flash[:alert].should match /Couldn't find order with/
end
end
end

View File

@@ -10,14 +10,9 @@
## If you submit a pull request containing new view or controller tests, it will not be
## merged.
require 'rails_helper'
describe AdminController do
login_member(:admin_member)
describe "GET admin/newsletter" do

View File

@@ -10,14 +10,9 @@
## If you submit a pull request containing new view or controller tests, it will not be
## merged.
require 'rails_helper'
describe AuthenticationsController do
before(:each) do
@member = FactoryGirl.create(:member)
sign_in @member
@@ -30,5 +25,4 @@ describe AuthenticationsController do
'credentials' => { 'token' => 'blah', 'secret' => 'blah' }
}
end
end

View File

@@ -10,14 +10,9 @@
## If you submit a pull request containing new view or controller tests, it will not be
## merged.
require 'rails_helper'
describe CommentsController do
before(:each) do
@member = FactoryGirl.create(:member)
sign_in @member
@@ -41,14 +36,14 @@ describe CommentsController do
describe "GET new" do
it "picks up post from params" do
post = FactoryGirl.create(:post)
get :new, {post_id: post.id}
get :new, { post_id: post.id }
assigns(:post).should eq(post)
end
it "assigns the old comments as @comments" do
post = FactoryGirl.create(:post)
old_comment = FactoryGirl.create(:comment, post: post)
get :new, {post_id: post.id}
get :new, { post_id: post.id }
assigns(:comments).should eq [old_comment]
end
@@ -63,7 +58,7 @@ describe CommentsController do
post = FactoryGirl.create(:post)
old_comment = FactoryGirl.create(:comment, post: post)
comment = FactoryGirl.create(:comment, post: post, author: @member)
get :edit, {id: comment.to_param}
get :edit, { id: comment.to_param }
assigns(:comments).should eq([comment, old_comment])
end
end
@@ -72,7 +67,7 @@ describe CommentsController do
describe "with valid params" do
it "redirects to the comment's post" do
comment = Comment.create! valid_attributes
put :update, {id: comment.to_param, comment: valid_attributes}
put :update, { id: comment.to_param, comment: valid_attributes }
response.should redirect_to(comment.post)
end
end
@@ -82,9 +77,8 @@ describe CommentsController do
it "redirects to the post the comment was on" do
comment = Comment.create! valid_attributes
post = comment.post
delete :destroy, {id: comment.to_param}
delete :destroy, { id: comment.to_param }
response.should redirect_to(post)
end
end
end

View File

@@ -10,14 +10,9 @@
## If you submit a pull request containing new view or controller tests, it will not be
## merged.
require 'rails_helper'
describe CropsController do
login_member(:crop_wrangling_member)
def valid_attributes
@@ -61,5 +56,4 @@ describe CropsController do
response.content_type.should eq("application/rss+xml")
end
end
end

Some files were not shown because too many files have changed in this diff Show More