diff --git a/.devcontainer/.env b/.devcontainer/.env new file mode 100644 index 000000000..2ba97513c --- /dev/null +++ b/.devcontainer/.env @@ -0,0 +1,2 @@ +# Ruby version +VARIANT=3.1.4 diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..5cb55287c --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,22 @@ +FROM mcr.microsoft.com/devcontainers/ruby:0-3.1-bullseye + +# Install Rails +RUN gem install rails:7.0.4 webdrivers:5.2.0 + +# Default value to allow debug server to serve content over GitHub Codespace's port forwarding service +# The value is a comma-separated list of allowed domains +ENV RAILS_DEVELOPMENT_HOSTS=".githubpreview.dev,.preview.app.github.dev,.app.github.dev" + +#RUN bundle +#RUN bundle exec rake db:create +#RUN bundle exec rake db:migrate + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + +# [Optional] Uncomment this line to install additional gems. +# RUN gem install + +# [Optional] Uncomment this line to install global node packages. +# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 diff --git a/.devcontainer/create-db-user.sql b/.devcontainer/create-db-user.sql new file mode 100644 index 000000000..291dfc427 --- /dev/null +++ b/.devcontainer/create-db-user.sql @@ -0,0 +1,2 @@ +CREATE USER vscode CREATEDB; +CREATE DATABASE vscode WITH OWNER vscode; diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..940d241e7 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,30 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ruby-rails-postgres +{ +"name": "Growstuff", +"dockerComposeFile": "docker-compose.yml", +"service": "app", +"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", + +// Features to add to the dev container. More info: https://containers.dev/features. +// Need something to get javascript working +"features": { + "ghcr.io/devcontainers/features/node:1": {} +}, + +// Use 'forwardPorts' to make a list of ports inside the container available locally. +// This can be used to network with other containers or the host. +"forwardPorts": [3000, 5432, 9200], + +// Use 'postCreateCommand' to run commands after the container is created. +// these don't actually work as postCreateCommands, you need to run them manually +// for some unknown reason, Github codespaces use rbenv and rvm simultaneously +// and you need both to be correct for it to work +"postCreateCommand": "nice -n 19 bundle install && nice -n 19 bundle exec rake db:create && nice -n 19 bundle exec rake db:migrate && nice -n19 bundle exec rake db:seed" + +// Configure tool-specific properties. +// "customizations": {}, + +// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. +// "remoteUser": "root" +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 000000000..e33d14dee --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,82 @@ +version: '3' + +services: + app: + build: + context: .. + dockerfile: .devcontainer/Dockerfile + depends_on: + db: + condition: service_healthy + elasticsearch: + condition: service_healthy + environment: + ELASTICSEARCH_URL: http://elasticsearch:9200/ + APP_DOMAIN_NAME: localhost:3000 + APP_PROTOCOL: http + DEVISE_SECRET_KEY: secret + GROWSTUFF_EMAIL: "noreply@test.growstuff.org" + GROWSTUFF_FLICKR_KEY: secretkey + GROWSTUFF_FLICKR_SECRET: secretsecret + GROWSTUFF_SITE_NAME: "Growstuff (local)" + RAILS_SECRET_TOKEN: supersecret + volumes: + - ../..:/workspaces:cached + + # Overrides default command so things don't shut down after the process ends. + command: sleep infinity + + db: + image: postgres:latest + restart: unless-stopped + volumes: + - postgres-data:/var/lib/postgresql/data + - ./create-db-user.sql:/docker-entrypoint-initdb.d/create-db-user.sql + environment: + POSTGRES_USER: postgres + POSTGRES_DB: growstuff_dev + POSTGRES_PASSWORD: postgres + ports: + - "5432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready"] + interval: 10s + timeout: 5s + retries: 5 + + elasticsearch: + image: docker.elastic.co/elasticsearch/elasticsearch:7.4.0 + container_name: elasticsearch + environment: + - xpack.security.enabled=false + - discovery.type=single-node + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: + soft: 65536 + hard: 65536 + cap_add: + - IPC_LOCK + healthcheck: + test: + [ + "CMD-SHELL", + "curl http://localhost:9200 | grep tagline", + ] + interval: 10s + timeout: 10s + retries: 120 + volumes: + - esdata01:/usr/share/elasticsearch/data + ports: + - 9200:9200 + - 9300:9300 + +volumes: + postgres-data: + certs: + driver: local + esdata01: + driver: local diff --git a/.ruby-version b/.ruby-version index ff365e06b..0aec50e6e 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.1.3 +3.1.4 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..bb8069bc8 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,129 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +info@growstuff.org. Any issues with a particular moderator can be reported to +any one of the other moderators. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/Gemfile b/Gemfile index 916597071..85637f08d 100644 --- a/Gemfile +++ b/Gemfile @@ -15,7 +15,7 @@ gem 'bundler', '>= 2.3.10' gem 'coffee-rails' gem 'haml' -gem 'sass-rails' +gem 'sassc-rails' # API data gem 'jsonapi-resources' diff --git a/Gemfile.lock b/Gemfile.lock index e0abee70a..e70c42dcf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,47 +26,47 @@ GEM remote: https://rubygems.org/ specs: abstract_type (0.0.7) - actioncable (7.0.4.2) - actionpack (= 7.0.4.2) - activesupport (= 7.0.4.2) + actioncable (7.0.4.3) + actionpack (= 7.0.4.3) + activesupport (= 7.0.4.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.4.2) - actionpack (= 7.0.4.2) - activejob (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + actionmailbox (7.0.4.3) + actionpack (= 7.0.4.3) + activejob (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.4.2) - actionpack (= 7.0.4.2) - actionview (= 7.0.4.2) - activejob (= 7.0.4.2) - activesupport (= 7.0.4.2) + actionmailer (7.0.4.3) + actionpack (= 7.0.4.3) + actionview (= 7.0.4.3) + activejob (= 7.0.4.3) + activesupport (= 7.0.4.3) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.0) - actionpack (7.0.4.2) - actionview (= 7.0.4.2) - activesupport (= 7.0.4.2) + actionpack (7.0.4.3) + actionview (= 7.0.4.3) + activesupport (= 7.0.4.3) rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.4.2) - actionpack (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + actiontext (7.0.4.3) + actionpack (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.4.2) - activesupport (= 7.0.4.2) + actionview (7.0.4.3) + activesupport (= 7.0.4.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -78,25 +78,25 @@ GEM activerecord (>= 4.2) active_record_union (1.3.0) activerecord (>= 4.0) - active_utils (3.4.0) + active_utils (3.4.1) activesupport (>= 4.2) i18n - activejob (7.0.4.2) - activesupport (= 7.0.4.2) + activejob (7.0.4.3) + activesupport (= 7.0.4.3) globalid (>= 0.3.6) - activemodel (7.0.4.2) - activesupport (= 7.0.4.2) - activerecord (7.0.4.2) - activemodel (= 7.0.4.2) - activesupport (= 7.0.4.2) - activestorage (7.0.4.2) - actionpack (= 7.0.4.2) - activejob (= 7.0.4.2) - activerecord (= 7.0.4.2) - activesupport (= 7.0.4.2) + activemodel (7.0.4.3) + activesupport (= 7.0.4.3) + activerecord (7.0.4.3) + activemodel (= 7.0.4.3) + activesupport (= 7.0.4.3) + activestorage (7.0.4.3) + actionpack (= 7.0.4.3) + activejob (= 7.0.4.3) + activerecord (= 7.0.4.3) + activesupport (= 7.0.4.3) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (7.0.4.2) + activesupport (7.0.4.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -104,7 +104,7 @@ GEM adamantium (0.2.0) ice_nine (~> 0.11.0) memoizable (~> 0.4.0) - addressable (2.8.1) + addressable (2.8.4) public_suffix (>= 2.0.2, < 6.0) anima (0.3.2) abstract_type (~> 0.0.7) @@ -114,10 +114,10 @@ GEM autoprefixer-rails (10.4.7.0) execjs (~> 2) bcrypt (3.1.18) - better_errors (2.9.1) - coderay (>= 1.0.0) + better_errors (2.10.0) erubi (>= 1.0.0) rack (>= 0.9.0) + rouge (>= 1.0.0) better_html (2.0.1) actionview (>= 6.0) activesupport (>= 6.0) @@ -144,7 +144,7 @@ GEM uniform_notifier (~> 1.11) byebug (11.1.3) cancancan (3.5.0) - capybara (3.38.0) + capybara (3.39.0) addressable matrix mini_mime (>= 0.1.3) @@ -170,7 +170,6 @@ GEM chartkick (5.0.1) codeclimate-test-reporter (1.0.9) simplecov (<= 0.13) - coderay (1.1.3) coffee-rails (5.0.0) coffee-script (>= 2.2.0) railties (>= 5.2.0) @@ -184,19 +183,19 @@ GEM adamantium (~> 0.2.0) equalizer (~> 0.0.9) concurrent-ruby (1.2.2) - connection_pool (2.3.0) + connection_pool (2.4.0) crass (1.0.6) csv_shaper (1.3.2) activesupport (>= 3.0.0) dalli (3.2.4) - database_cleaner (2.0.1) - database_cleaner-active_record (~> 2.0.0) - database_cleaner-active_record (2.0.0) + database_cleaner (2.0.2) + database_cleaner-active_record (>= 2, < 3) + database_cleaner-active_record (2.1.0) activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) date (3.3.3) - devise (4.9.0) + devise (4.9.2) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) @@ -233,7 +232,7 @@ GEM factory_bot_rails (6.2.0) factory_bot (~> 6.2.0) railties (>= 5.0.0) - faker (3.1.1) + faker (3.2.0) i18n (>= 1.8.11, < 2) faraday (1.10.3) faraday-em_http (~> 1.0) @@ -306,7 +305,7 @@ GEM httparty (0.21.0) mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) - i18n (1.12.0) + i18n (1.13.0) concurrent-ruby (~> 1.0) i18n-tasks (1.0.12) activesupport (>= 4.0.2) @@ -351,7 +350,7 @@ GEM listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.19.1) + loofah (2.20.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.8.1) @@ -379,7 +378,7 @@ GEM mini_magick (4.12.0) mini_mime (1.1.2) mini_portile2 (2.8.1) - minitest (5.17.0) + minitest (5.18.0) moneta (1.0.0) multi_json (1.15.0) multi_xml (0.6.0) @@ -393,14 +392,14 @@ GEM timeout net-smtp (0.3.3) net-protocol - nio4r (2.5.8) - nokogiri (1.14.2) + nio4r (2.5.9) + nokogiri (1.14.3) mini_portile2 (~> 2.8.0) racc (~> 1.4) - nokogiri (1.14.2-x86_64-linux) + nokogiri (1.14.3-x86_64-linux) racc (~> 1.4) oauth (0.5.6) - oj (3.14.2) + oj (3.14.3) omniauth (1.9.2) hashie (>= 3.4.6) rack (>= 1.6.2, < 3) @@ -414,43 +413,43 @@ GEM omniauth-oauth (~> 1.1) rack orm_adapter (0.5.0) - parallel (1.22.1) - parser (3.2.1.1) + parallel (1.23.0) + parser (3.2.2.0) ast (~> 2.4.1) percy-capybara (5.0.0) capybara (>= 3) - pg (1.4.6) + pg (1.5.3) platform-api (3.5.0) heroics (~> 0.1.1) moneta (~> 1.0.0) rate_throttle_client (~> 0.1.0) popper_js (1.16.1) public_suffix (5.0.1) - puma (6.1.1) + puma (6.2.2) nio4r (~> 2.0) query_diet (0.7.1) racc (1.6.2) - rack (2.2.6.3) - rack-cors (2.0.0) + rack (2.2.7) + rack-cors (2.0.1) rack (>= 2.0.0) - rack-protection (3.0.5) + rack-protection (3.0.6) rack - rack-test (2.0.2) + rack-test (2.1.0) rack (>= 1.3) - rails (7.0.4.2) - actioncable (= 7.0.4.2) - actionmailbox (= 7.0.4.2) - actionmailer (= 7.0.4.2) - actionpack (= 7.0.4.2) - actiontext (= 7.0.4.2) - actionview (= 7.0.4.2) - activejob (= 7.0.4.2) - activemodel (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + rails (7.0.4.3) + actioncable (= 7.0.4.3) + actionmailbox (= 7.0.4.3) + actionmailer (= 7.0.4.3) + actionpack (= 7.0.4.3) + actiontext (= 7.0.4.3) + actionview (= 7.0.4.3) + activejob (= 7.0.4.3) + activemodel (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) bundler (>= 1.15.0) - railties (= 7.0.4.2) + railties (= 7.0.4.3) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -468,9 +467,9 @@ GEM rails_stdout_logging rails_serve_static_assets (0.0.5) rails_stdout_logging (0.0.5) - railties (7.0.4.2) - actionpack (= 7.0.4.2) - activesupport (= 7.0.4.2) + railties (7.0.4.3) + actionpack (= 7.0.4.3) + activesupport (= 7.0.4.3) method_source rake (>= 12.2) thor (~> 1.0) @@ -482,13 +481,14 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - redis-client (0.12.2) + redis-client (0.14.1) connection_pool - regexp_parser (2.7.0) + regexp_parser (2.8.0) responders (3.1.0) actionpack (>= 5.2) railties (>= 5.2) rexml (3.2.5) + rouge (4.1.0) rspec (3.11.0) rspec-core (~> 3.11.0) rspec-expectations (~> 3.11.0) @@ -519,35 +519,35 @@ GEM concord (~> 0.1) parser (>= 2.6) rspec (~> 3.0) - rswag-api (2.8.0) + rswag-api (2.9.0) railties (>= 3.1, < 7.1) - rswag-specs (2.8.0) + rswag-specs (2.9.0) activesupport (>= 3.1, < 7.1) json-schema (>= 2.2, < 4.0) railties (>= 3.1, < 7.1) rspec-core (>= 2.14) - rswag-ui (2.8.0) + rswag-ui (2.9.0) actionpack (>= 3.1, < 7.1) railties (>= 3.1, < 7.1) - rubocop (1.48.0) + rubocop (1.50.2) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.26.0, < 2.0) + rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.27.0) + rubocop-ast (1.28.0) parser (>= 3.2.1.0) rubocop-capybara (2.17.1) rubocop (~> 1.41) - rubocop-rails (2.18.0) + rubocop-rails (2.19.1) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) - rubocop-rspec (2.19.0) + rubocop-rspec (2.20.0) rubocop (~> 1.33) rubocop-capybara (~> 2.17) ruby-progressbar (1.13.0) @@ -561,8 +561,6 @@ GEM sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - sass-rails (6.0.0) - sassc-rails (~> 2.1, >= 2.1.1) sassc (2.4.0) ffi (~> 1.9) sassc-rails (2.1.2) @@ -577,11 +575,11 @@ GEM activemodel (>= 5) elasticsearch (>= 6, < 7.14) hashie - selenium-webdriver (4.8.1) + selenium-webdriver (4.9.0) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) - sidekiq (7.0.6) + sidekiq (7.0.9) concurrent-ruby (< 2) connection_pool (>= 2.3.0) rack (>= 2.2.4) @@ -734,7 +732,7 @@ DEPENDENCIES rubocop-rails rubocop-rspec ruby-units - sass-rails + sassc-rails scout_apm searchkick selenium-webdriver @@ -751,7 +749,7 @@ DEPENDENCIES xmlrpc RUBY VERSION - ruby 3.1.3p185 + ruby 3.1.4p223 BUNDLED WITH 2.3.11 diff --git a/app/assets/javascripts/places.js.erb b/app/assets/javascripts/places.js.erb index 93e5e9538..7cc39bb12 100644 --- a/app/assets/javascripts/places.js.erb +++ b/app/assets/javascripts/places.js.erb @@ -58,6 +58,7 @@ function showMap(placesmap) { }); function fetchCropsForMap(url) { + var n = 0; $.getJSON(url, function(crop_data) { $.each(crop_data['data'], function(i, p) { if (p.attributes.latitude && p.attributes.longitude) { @@ -78,7 +79,8 @@ function showMap(placesmap) { markers.addLayer(marker); } }); - if (crop_data['links']['next']) { + // We fetch pages of 10 at a time. Stop after 200 crops; so we are showing only 'active' plantings. + if (crop_data['links']['next'] && n++ < 20) { fetchCropsForMap(crop_data['links']['next']) } return crop_data; diff --git a/app/controllers/plantings_controller.rb b/app/controllers/plantings_controller.rb index bd4452661..6c02f5128 100644 --- a/app/controllers/plantings_controller.rb +++ b/app/controllers/plantings_controller.rb @@ -12,7 +12,7 @@ class PlantingsController < DataController if params[:member_slug] @owner = Member.find_by(slug: params[:member_slug]) - where['owner_id'] = @owner.id + where['owner_id'] = @owner.id unless @owner.nil? end if params[:crop_slug] diff --git a/app/models/crop.rb b/app/models/crop.rb index b47999fb5..020692387 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -54,6 +54,7 @@ class Crop < ApplicationRecord message: 'is not a valid English Wikipedia URL' }, if: :approved? + validates :name, uniqueness: { scope: :approval_status }, if: :pending? def to_s name diff --git a/app/views/gardens/_form.html.haml b/app/views/gardens/_form.html.haml index f55011592..8ab82bc9b 100644 --- a/app/views/gardens/_form.html.haml +++ b/app/views/gardens/_form.html.haml @@ -27,7 +27,7 @@ - else = link_to "Change your location.", edit_member_registration_path .row - .col-md-5.col-12= f.number_field :area, class: 'input-small' + .col-md-5.col-12= f.number_field :area, class: 'input-small', step: "any" .col-md-7.col-12= f.select(:area_unit, Garden::AREA_UNITS_VALUES, { include_blank: false }) .col-12= f.select(:garden_type_id, GardenType.all.order(:name).pluck(:name, :id), selected: @garden.garden_type_id, include_blank: true) diff --git a/config/database.yml b/config/database.yml index 72f6533ae..c01af6fa2 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,10 +1,16 @@ development: adapter: postgresql database: growstuff_dev + user: postgres + password: postgres + host: db test: adapter: postgresql database: growstuff_test + user: postgres + password: postgres + host: db production: adapter: postgresql diff --git a/config/elasticsearch.yml b/config/elasticsearch.yml new file mode 100644 index 000000000..bad9c21a8 --- /dev/null +++ b/config/elasticsearch.yml @@ -0,0 +1,5 @@ +development: &default + host: 'http://es01:9200' + log: true +test: + host: 'http://es01:9200' diff --git a/config/environments/development.rb b/config/environments/development.rb index 0368822e9..47de02a04 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -67,6 +67,7 @@ Rails.application.configure do config.action_mailer.delivery_method = :letter_opener config.host = 'localhost:3000' + config.hosts << ".preview.app.github.dev" config.analytics_code = '' config.action_controller.action_on_unpermitted_parameters = :raise diff --git a/config/environments/production.rb b/config/environments/production.rb index d16a4af0d..0b161c458 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -83,7 +83,7 @@ Rails.application.configure do config.active_support.deprecation = :notify # Use default logging formatter so that PID and timestamp are not suppressed. - config.log_formatter = ::Logger::Formatter.new + config.log_formatter = Logger::Formatter.new # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false @@ -103,11 +103,11 @@ Rails.application.configure do ActionMailer::Base.delivery_method = :smtp config.host = ENV['HOST'] - config.analytics_code = <<-eos + config.analytics_code = <<-GET_CLICKY_SCRIPT - eos + GET_CLICKY_SCRIPT config.active_job.queue_adapter = :sidekiq # Use a different logger for distributed setups. diff --git a/db/schema.rb b/db/schema.rb index 0d0d6a357..3cd83979d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -2,25 +2,52 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# This file is the source Rails uses to define your schema when running `rails -# db:schema:load`. When creating a new database, `rails db:schema:load` tends to +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to # be faster and is potentially less error prone than running all of your # migrations from scratch. Old migrations may fail to apply correctly if those # migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_08_15_012538) do - +ActiveRecord::Schema[7.0].define(version: 2023_03_13_015323) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + create_table "active_storage_attachments", force: :cascade do |t| + t.string "name", null: false + t.string "record_type", null: false + t.bigint "record_id", null: false + t.bigint "blob_id", null: false + t.datetime "created_at", null: false + t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" + t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true + end + + create_table "active_storage_blobs", force: :cascade do |t| + t.string "key", null: false + t.string "filename", null: false + t.string "content_type" + t.text "metadata" + t.string "service_name", null: false + t.bigint "byte_size", null: false + t.string "checksum" + t.datetime "created_at", null: false + t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true + end + + create_table "active_storage_variant_records", force: :cascade do |t| + t.bigint "blob_id", null: false + t.string "variation_digest", null: false + t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true + end + create_table "alternate_names", id: :serial, force: :cascade do |t| t.string "name", null: false t.integer "crop_id", null: false t.integer "creator_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil end create_table "authentications", id: :serial, force: :cascade do |t| @@ -29,8 +56,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.string "uid" t.string "token" t.string "secret" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "name" t.index ["member_id"], name: "index_authentications_on_member_id" end @@ -56,8 +83,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.string "file_file_name" t.string "description", limit: 2048 t.integer "position", default: 0, null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.index ["site_id", "block_id"], name: "index_comfy_cms_files_on_site_id_and_block_id" t.index ["site_id", "file_file_name"], name: "index_comfy_cms_files_on_site_id_and_file_file_name" t.index ["site_id", "label"], name: "index_comfy_cms_files_on_site_id_and_label" @@ -69,10 +96,10 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.text "content" t.string "record_type" t.integer "record_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "tag", default: "text", null: false - t.datetime "datetime" + t.datetime "datetime", precision: nil t.boolean "boolean", default: false, null: false t.index ["identifier"], name: "index_comfy_cms_fragments_on_identifier" t.index ["record_id", "record_type"], name: "index_comfy_cms_fragments_on_record_id_and_record_type" @@ -88,8 +115,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.text "css" t.text "js" t.integer "position", default: 0, null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.index ["parent_id", "position"], name: "index_comfy_cms_layouts_on_parent_id_and_position" t.index ["site_id", "identifier"], name: "index_comfy_cms_layouts_on_site_id_and_identifier", unique: true end @@ -106,8 +133,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.integer "position", default: 0, null: false t.integer "children_count", default: 0, null: false t.boolean "is_published", default: true, null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.index ["parent_id", "position"], name: "index_comfy_cms_pages_on_parent_id_and_position" t.index ["site_id", "full_path"], name: "index_comfy_cms_pages_on_site_id_and_full_path" end @@ -116,7 +143,7 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.string "record_type", null: false t.integer "record_id", null: false t.text "data" - t.datetime "created_at" + t.datetime "created_at", precision: nil t.index ["record_type", "record_id", "created_at"], name: "index_cms_revisions_on_rtype_and_rid_and_created_at" end @@ -135,8 +162,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.string "identifier", null: false t.text "content" t.integer "position", default: 0, null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.index ["site_id", "identifier"], name: "index_comfy_cms_snippets_on_site_id_and_identifier", unique: true t.index ["site_id", "position"], name: "index_comfy_cms_snippets_on_site_id_and_position" end @@ -148,8 +175,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.string "label", null: false t.text "content_cache" t.boolean "is_published", default: true, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["is_published"], name: "index_comfy_cms_translations_on_is_published" t.index ["locale"], name: "index_comfy_cms_translations_on_locale" t.index ["page_id"], name: "index_comfy_cms_translations_on_page_id" @@ -159,15 +186,15 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.integer "post_id", null: false t.integer "author_id", null: false t.text "body", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil end create_table "crop_companions", force: :cascade do |t| t.integer "crop_a_id", null: false t.integer "crop_b_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false end create_table "crop_posts", id: false, force: :cascade do |t| @@ -180,8 +207,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do create_table "crops", id: :serial, force: :cascade do |t| t.string "name", null: false t.string "en_wikipedia_url" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "slug" t.integer "parent_id" t.integer "plantings_count", default: 0 @@ -206,16 +233,16 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do create_table "follows", id: :serial, force: :cascade do |t| t.integer "follower_id" t.integer "followed_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil end create_table "forums", id: :serial, force: :cascade do |t| t.string "name", null: false t.text "description", null: false t.integer "owner_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "slug" t.index ["slug"], name: "index_forums_on_slug", unique: true end @@ -223,8 +250,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do create_table "garden_types", force: :cascade do |t| t.text "name", null: false t.text "slug", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["name"], name: "index_garden_types_on_name", unique: true t.index ["slug"], name: "index_garden_types_on_slug", unique: true end @@ -233,8 +260,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.string "name", null: false t.integer "owner_id" t.string "slug", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.text "description" t.boolean "active", default: true t.string "location" @@ -261,8 +288,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.decimal "quantity" t.string "unit" t.text "description" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "slug" t.decimal "weight_quantity" t.string "weight_unit" @@ -283,8 +310,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.string "likeable_type" t.integer "likeable_id" t.string "categories", array: true - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.index ["likeable_id"], name: "index_likes_on_likeable_id" t.index ["likeable_type", "likeable_id"], name: "index_likes_on_likeable_type_and_likeable_id" t.index ["member_id"], name: "index_likes_on_member_id" @@ -294,16 +321,16 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.string "unsubscriber_type" t.integer "unsubscriber_id" t.integer "conversation_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["conversation_id"], name: "index_mailboxer_conversation_opt_outs_on_conversation_id" t.index ["unsubscriber_id", "unsubscriber_type"], name: "index_mailboxer_conversation_opt_outs_on_unsubscriber_id_type" end create_table "mailboxer_conversations", id: :serial, force: :cascade do |t| t.string "subject", default: "" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false end create_table "mailboxer_notifications", id: :serial, force: :cascade do |t| @@ -318,10 +345,10 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.string "notified_object_type" t.integer "notified_object_id" t.string "attachment" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.boolean "global", default: false - t.datetime "expires" + t.datetime "expires", precision: nil t.index ["conversation_id"], name: "index_mailboxer_notifications_on_conversation_id" t.index ["notified_object_id", "notified_object_type"], name: "index_mailboxer_notifications_on_notified_object_id_and_type" t.index ["notified_object_type", "notified_object_id"], name: "mailboxer_notifications_notified_object" @@ -337,8 +364,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.boolean "trashed", default: false t.boolean "deleted", default: false t.string "mailbox_type", limit: 25 - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.boolean "is_delivered", default: false t.string "delivery_method" t.string "message_id" @@ -353,22 +380,22 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false t.string "reset_password_token" - t.datetime "reset_password_sent_at" - t.datetime "remember_created_at" + t.datetime "reset_password_sent_at", precision: nil + t.datetime "remember_created_at", precision: nil t.integer "sign_in_count", default: 0 - t.datetime "current_sign_in_at" - t.datetime "last_sign_in_at" + t.datetime "current_sign_in_at", precision: nil + t.datetime "last_sign_in_at", precision: nil t.string "current_sign_in_ip" t.string "last_sign_in_ip" t.string "confirmation_token" - t.datetime "confirmed_at" - t.datetime "confirmation_sent_at" + t.datetime "confirmed_at", precision: nil + t.datetime "confirmation_sent_at", precision: nil t.string "unconfirmed_email" t.integer "failed_attempts", default: 0 t.string "unlock_token" - t.datetime "locked_at" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "locked_at", precision: nil + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "login_name" t.string "slug" t.boolean "tos_agreement" @@ -385,7 +412,7 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.integer "gardens_count" t.integer "harvests_count" t.integer "seeds_count" - t.datetime "discarded_at" + t.datetime "discarded_at", precision: nil t.integer "photos_count" t.integer "forums_count" t.index ["confirmation_token"], name: "index_members_on_confirmation_token", unique: true @@ -408,8 +435,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.text "body" t.boolean "read", default: false t.integer "post_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil end create_table "orders_products", id: false, force: :cascade do |t| @@ -421,8 +448,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.integer "photo_id", null: false t.integer "photographable_id", null: false t.string "photographable_type", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "crop_id" t.index ["photographable_id", "photographable_type", "photo_id"], name: "items_to_photos_idx", unique: true t.index ["photographable_id", "photographable_type"], name: "photographable_idx" @@ -432,14 +459,14 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.integer "owner_id", null: false t.string "thumbnail_url", null: false t.string "fullsize_url", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "title", null: false t.string "license_name", null: false t.string "license_url" t.string "link_url", null: false t.string "source_id" - t.datetime "date_taken" + t.datetime "date_taken", precision: nil t.integer "likes_count", default: 0 t.string "source" t.index ["fullsize_url"], name: "index_photos_on_fullsize_url", unique: true @@ -459,8 +486,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do create_table "plant_parts", id: :serial, force: :cascade do |t| t.string "name" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "slug" t.integer "harvests_count", default: 0 end @@ -471,8 +498,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.date "planted_at" t.integer "quantity" t.text "description" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "slug" t.string "sunniness" t.string "planted_from" @@ -491,8 +518,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.integer "author_id", null: false t.string "subject", null: false t.text "body", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "slug" t.integer "forum_id" t.integer "likes_count", default: 0 @@ -504,8 +531,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do create_table "roles", id: :serial, force: :cascade do |t| t.string "name", null: false t.text "description" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "slug" t.index ["slug"], name: "index_roles_on_slug", unique: true end @@ -513,8 +540,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do create_table "scientific_names", id: :serial, force: :cascade do |t| t.string "name", null: false t.integer "crop_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.integer "creator_id" end @@ -524,8 +551,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.text "description" t.integer "quantity" t.date "plant_before" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "tradable_to", default: "nowhere" t.string "slug" t.integer "days_until_maturity_min" @@ -540,6 +567,8 @@ ActiveRecord::Schema.define(version: 2020_08_15_012538) do t.index ["slug"], name: "index_seeds_on_slug", unique: true end + add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" + add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "harvests", "plantings" add_foreign_key "mailboxer_conversation_opt_outs", "mailboxer_conversations", column: "conversation_id", name: "mb_opt_outs_on_conversations_id" add_foreign_key "mailboxer_notifications", "mailboxer_conversations", column: "conversation_id", name: "notifications_on_conversation_id"