Compare commits

...

59 Commits

Author SHA1 Message Date
52c3d0c7a0 Fixed two bugs that were introduced when we changed the conference registration process to accommodate virtual conferences. 2025-01-31 00:35:05 -05:00
15ecc409b1 Corrected ofelia typo. 2024-01-15 22:54:56 -05:00
dffbba76ce Updates browserlist daily with a ofelia job, so that caniuse generates the newest browsers. 2024-01-16 03:34:50 +00:00
a1f2b7ccfb Getting more detail about response from ReCaptcha v3 2023-07-26 03:59:04 +00:00
ed6cd6f9d6 Yay, ReCaptcha v3 is now working properly, still need to perfect the render page. 2023-07-25 10:54:14 +00:00
4ea41449a3 Bumping up to only humans. 2023-07-25 08:23:18 +00:00
8d8978eec6 Adds ReCaptcha v3 to all the other known sign-ins 2023-07-25 06:05:49 +00:00
e764ccc1ff Recaptcha v3 should be working now, but you must have a site key and secret key since env is hardwired into head. 2023-07-25 05:12:33 +00:00
9ea241f8ec Corrects spelling mistake 2023-07-25 04:49:25 +00:00
32b3904c39 ReCaptcha v3 - almost working 2023-07-25 04:31:44 +00:00
4d39814468 Improves ofelia documentation, changes job name for docker-compose.yml to test version. Comments out cantainer_name to avoid container conflicts with multiple instances. 2023-07-23 02:25:59 -04:00
e13ee3f1d9 Updating this file, just an initial start. 2023-07-18 02:45:47 -04:00
213305ff31 Adds ofelia labels to schedule caniuse.js jobs. Updates the README, to provide an example ofelia job scheduler service. 2023-07-18 02:24:09 -04:00
3a7cc21ba5 Noting best way to export database with pg_dump. 2023-07-17 22:28:21 -04:00
9f89edda34 Correcting a spelling mistake. 2023-07-17 18:25:27 -04:00
e1dcc065c6 Didn't realize the change was that this was commented out. Corrected. 2023-07-17 18:24:08 -04:00
451c0addfd Put logic in wrong definition. Copy/paste mistake. 2023-07-17 17:59:35 -04:00
6324c03895 Adds new registration step module, and some testing code. 2023-07-17 21:09:57 +00:00
0e502373a9 Changes steps, and adds debug code piped to a file. 2023-07-17 21:01:26 +00:00
48a1ca3725 Adds debug code piped to a file. 2023-07-17 20:55:42 +00:00
58c21b5e4a Updates views 2023-07-17 20:05:35 +00:00
0f08affd23 Locale changes 2023-07-17 19:38:25 +00:00
4b651a0e18 This removes the contact form. 2023-07-17 19:22:37 +00:00
99c1e8d204 Adds new pnpm dependency files. 2023-07-17 19:18:32 +00:00
52f5f51f50 Modernizes docker-compose, add git-lfs to Dockerfile. 2023-07-17 15:04:26 -04:00
606e44f059 Moved to pnpm. Added caniuse.js to Dockerfile. 2023-07-17 13:27:40 -04:00
a0305d8463 Removed erroneous files added during earlier processing 2023-07-17 07:55:39 +00:00
8aba45d10e Solves the broken Bumbleberry issue using browserslist (caniuse-lite) to identify and copy modern css for new browsers, while maintaining backwards compatibility with obscure browsers. 2023-07-17 07:37:11 +00:00
a35f0df3ba Ignore node_module & public/stylesheets 2023-07-15 04:59:50 +00:00
02c685db6a Adding important lock files to the reporsitory 2023-07-13 03:11:25 -04:00
437d093486 Development improvements: Don't save temp containers, and recreate volumes by not making them external. 2023-07-13 03:06:58 -04:00
bdbeb85329 Didn't me an to commit this file. :) 2023-07-04 15:09:01 -04:00
fa25fdd1ec For consistency, minor change to documentation in this file. 2023-07-04 15:07:21 -04:00
7f1244457d Modernizes the docker command in relation to compose, which is now a plugin. 2023-07-04 15:01:12 -04:00
c4e0733cd5 Updated readme to reflect the requirement to install git-lfs. 2023-07-04 14:00:59 -04:00
16497c1c86 spelling - xml to yaml 2022-07-08 14:29:15 -04:00
336142d54a spelling - xml to yml 2022-07-08 14:28:25 -04:00
711bdbb52d change some wording 2022-06-30 21:47:04 -04:00
20d5443a61 better 2022-06-30 17:59:32 -04:00
fdc41fe4f8 Improvements - now have letsencrypt documentation 2022-06-30 17:54:04 -04:00
fe7b0e43f6 Commonly used environmental variables in .env 2022-06-30 17:49:12 -04:00
12a1a22551 Details about the bike_bike_advanced_environment file 2022-06-30 17:39:17 -04:00
176637ab2e What to do after installation 2022-06-30 15:08:44 -04:00
Jonathan Rosenbaum
89748c6927 Adds sidekiq as its own container process.
Former-commit-id: 6e47f12e7ad28aa5f09999439f60bc06bb50bff9
2021-12-27 20:39:49 -05:00
Jonathan Rosenbaum
0e776f25e0 Adds sidekiq Web UI @ /sidekiq . Next shall add sidekiq container to get the daemon rolling.
Former-commit-id: 5a41a312b6dbdbe533b3e73786ed3ff0f85e98e5
2021-12-27 05:27:14 -05:00
Jonathan Rosenbaum
65a3c97fc8 Adds redis container, this fixes delayed mail error which uses sidekiq/redis, however, emails only go out on test becasue a non-delayed method is utilized. Trying to figure out why the existing is not working.
Former-commit-id: b5b0b5f4279622ff5091ca4b365293c8a7a77d31
2021-12-27 04:01:50 -05:00
Jonathan Rosenbaum
a5a13930e5 Adds more enlightenment for switching from development to production; adds vim and less to Dockerfile.
Former-commit-id: a8c6c72a9c28f960a955ead231d7d17ff732630f
2021-12-27 01:36:56 -05:00
Jonathan Rosenbaum
79743c1449 Adds development mode, improves the assets, updates the README with helpful information!
Former-commit-id: c95e624de930ea56432330beed495abc493fe539
2021-12-26 22:08:16 -05:00
Jonathan Rosenbaum
d288f192fa Allow dots in conference names. This wasn't an accent issue. Now something like conferences/Ciudad.de.México.22 works.
Good info at https://prathamesh.tech/2020/06/15/allowing-dots-in-rails-routes/ .


Former-commit-id: 457bfdbc041102e6ce13a629db6dbf417a97f56e
2021-12-26 21:44:05 -05:00
Jonathan Rosenbaum
b3b6d41738 This removes any env reference from the rails command, since RAILS_ENV handles this easier, and changes Administrate to Administer, which is the more common spelling.
Former-commit-id: b1dbdadd8c1dda46ec815194d5fb86f02c0cea90
2021-12-25 15:48:28 -05:00
Jonathan Rosenbaum
f65cab24ab This adds ADMIN_EMAIL for those places in the code where godwin's email address was hardcoded.
Former-commit-id: cdddb0dc7a68df8ed69121ea8eb55067e6502bff
2021-12-25 14:53:46 -05:00
d3968bbea4 More bumbleberry workarounds, until bumbleberry:update is working properly.
Former-commit-id: 349a641dfa63413b5a6e2e39769393ce0969e806
2021-12-25 14:34:36 -05:00
e3f178b3fa Adds untracked files of substance that were committed to the bikebike/bikebike repository.
Former-commit-id: 327188df797c9af152a395299976471cf3df024b
2021-12-23 14:37:42 -05:00
8029661917 Adds the changes from bikebike/bikebike for tracked files that weren't committed to git.
Former-commit-id: 23acad3a6de4f349390d87a88884b754abefdcfb
2021-12-23 14:28:32 -05:00
cb0bf52632 Yay, adds upload external volume!
Former-commit-id: 5c21a7608f59bda3bea340d2a209084253d5dda6
2021-12-23 14:05:00 -05:00
55d0aefe6a Adding the erb for app_config, note that before this file was in .gitignore, but now
environmental variables are being utilized.


Former-commit-id: 819a94fb2a0ab92081ccec35c6a413367efb3856
2021-12-23 04:07:13 -05:00
962ee1a4d5 Fine adjustments from lots of testing.
Former-commit-id: cd98441fd45b8d14b3b757bdc21cbd64347acd4a
2021-12-23 03:59:46 -05:00
9fe8c70ea6 This successfully builds a working bikebike rails app with Docker!
Former-commit-id: 0a55db70c4049243d5eb6c164698c93f49b1746a
2021-12-22 22:45:37 -05:00
Godwin
df5cce9efa
Copy edits for the housing info page
* Spanish housing copy changes

* French housing copy changes

* English housing copy changes
2019-03-02 09:08:14 -08:00
44 changed files with 1916 additions and 351 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.tar.gz filter=lfs diff=lfs merge=lfs -text

9
.gitignore vendored
View File

@ -8,7 +8,9 @@
!.openshift !.openshift
*~ *~
# Docker.gitignore
.env
bike_bike_advanced_environment
# OSX.gitignore # OSX.gitignore
.DS_Store .DS_Store
@ -79,4 +81,7 @@ brakeman.html
/config/settings/local.rb /config/settings/local.rb
/nbproject/private/ /nbproject/private/
/config/database.yml /config/database.yml
/config/app_config.yml
# Ignore node_module & public/stylesheets
node_modules/*
public/stylesheets

35
Dockerfile Normal file
View File

@ -0,0 +1,35 @@
############
# BikeBike #
############
FROM ruby:2.5
MAINTAINER Jonathan Rosenbaum <bike@bikelover.org>
COPY . /app/BikeBike
RUN apt-get update && apt-get install -y nodejs postgresql-client vim less git-lfs
RUN curl -fsSL https://get.pnpm.io/install.sh | bash - && /root/.local/share/pnpm/pnpm add browserslist
# Note: phantomjs has been deprecated in favor of headless chrome
WORKDIR /app/BikeBike
RUN mkdir -p public/stylesheets/application \
-p public/stylesheets/web-fonts \
-p public/stylesheets/admin \
&& tar xvfz bumbleberry-application.tar.gz -C public/stylesheets/application \
&& tar xvfz bumbleberry-web-fonts.tar.gz -C public/stylesheets/web-fonts \
&& tar xvfz bumbleberry-admin.tar.gz -C public/stylesheets/admin \
&& /app/BikeBike/caniuse.js
RUN bundle install
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]

16
Gemfile
View File

@ -1,9 +1,9 @@
source 'http://rubygems.org' source 'http://rubygems.org'
gem 'rails', '4.2.0' gem 'rails', '4.2.8'
gem 'pg' gem 'pg', '0.21.0'
gem 'rake', '11.1.2' gem 'rake', '12.3.3'
gem 'ruby_dep', '1.3.1' # Lock at 1.3.1 since 1.4 requires ruby 2.5. We should unlock once we upgrade the ruby version on our server gem 'ruby_dep', '1.4' # Lock at 1.3.1 since 1.4 requires ruby 2.5. We should unlock once we upgrade the ruby version on our server
gem 'rack-mini-profiler' gem 'rack-mini-profiler'
@ -41,17 +41,18 @@ gem 'sitemap_generator'
gem 'sass-json-vars' gem 'sass-json-vars'
gem 'redcarpet' gem 'redcarpet'
gem 'to_spreadsheet', git: 'https://github.com/glebm/to_spreadsheet.git' gem 'to_spreadsheet', git: 'https://github.com/glebm/to_spreadsheet.git'
gem 'net-ssh', '4.1.0'
group :development do group :development do
gem 'better_errors', '2.2.0' gem 'better_errors', '2.2.0'
gem 'binding_of_caller' gem 'binding_of_caller'
gem 'meta_request' gem 'meta_request'
gem 'capistrano', '~> 3.1' gem 'capistrano', '~> 3.1'
gem 'capistrano-rails', '~> 1.1' gem 'capistrano-rails', '~> 1.1'
gem 'capistrano-faster-assets', '~> 1.0' gem 'capistrano-faster-assets', '~> 1.0'
gem 'eventmachine', git: 'https://github.com/krzcho/eventmachine', :branch => 'master' gem 'eventmachine', git: 'https://github.com/eventmachine/eventmachine', :branch => 'master'
gem 'thin' gem 'thin'
gem 'rubocop', require: false gem 'rubocop', require: false
gem 'haml-lint', require: false gem 'haml-lint', require: false
@ -67,6 +68,7 @@ group :test do
gem 'guard-cucumber' gem 'guard-cucumber'
gem 'poltergeist' gem 'poltergeist'
gem 'capybara', '2.15.1'
gem 'capybara-email' gem 'capybara-email'
gem 'guard-rspec' gem 'guard-rspec'
gem 'factory_girl_rails' gem 'factory_girl_rails'
@ -93,7 +95,7 @@ end
platforms 'mswin', 'mingw' do platforms 'mswin', 'mingw' do
gem 'tzinfo-data' gem 'tzinfo-data'
group :test do group :test do
gem 'wdm', '>= 0.1.0' gem 'wdm', '>= 0.1.0'
gem 'win32console', require: false gem 'win32console', require: false

696
Gemfile.lock Normal file
View File

@ -0,0 +1,696 @@
GIT
remote: https://github.com/bikebike/bikecollectives_core.git
revision: 308dd1f8a8dae5232a77ba16e7c0725ba41bb874
branch: master
specs:
bikecollectives_core (0.1.0)
activerecord-session_store
carrierwave
carrierwave-imageoptimizer
haml
launchy
letter_opener
mini_magick
pg
premailer-rails
rails (~> 4.2.0)
redcarpet
sass
sass-json-vars
sass-rails
sidekiq
uglifier (>= 1.3.0)
GIT
remote: https://github.com/bumbleberry/bumbleberry.git
revision: 0ab0762a118c096886eee85e93b5da2d2c6a314a
branch: master
specs:
bumbleberry (0.0.1)
blockspring
cairo
railties
rsvg2
sass-json-vars
sass-rails
GIT
remote: https://github.com/eventmachine/eventmachine
revision: df4ab0068e5e9f504096584093a74510d0dac6c8
branch: master
specs:
eventmachine (1.3.0.dev.1)
GIT
remote: https://github.com/glebm/to_spreadsheet.git
revision: 80203fd1f4e57a6fe83ea9d677e42bf7cb8188d3
specs:
to_spreadsheet (1.1.0)
caxlsx
chronic
nokogiri
rails
responders
GIT
remote: https://github.com/lingua-franca/lingua_franca.git
revision: 49dd2d0ada3754d35d8fbd020378e770b9a99476
branch: master
specs:
lingua_franca (0.0.1)
diffy
forgery
http_accept_language
i18n
rails (~> 4.2.0.rc2)
rails-i18n
rubyzip
GIT
remote: https://github.com/lingua-franca/marmara.git
revision: 76e2406fcdb793e6ca1946e5d3f9125cf0076485
branch: master
specs:
marmara (1.0.2)
css_parser (>= 1.5.0.pre)
GIT
remote: https://github.com/tg90nor/sorcery.git
revision: 79b69a87ce168c47fab76921874aa7e8cb727002
branch: make-facebook-provider-use-json-token-parser
specs:
sorcery (0.10.3)
bcrypt (~> 3.1)
oauth (~> 0.4, >= 0.4.4)
oauth2 (~> 1.0, >= 0.8.0)
GEM
remote: http://rubygems.org/
specs:
actionmailer (4.2.8)
actionpack (= 4.2.8)
actionview (= 4.2.8)
activejob (= 4.2.8)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (4.2.8)
actionview (= 4.2.8)
activesupport (= 4.2.8)
rack (~> 1.6)
rack-test (~> 0.6.2)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (4.2.8)
activesupport (= 4.2.8)
builder (~> 3.1)
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
activejob (4.2.8)
activesupport (= 4.2.8)
globalid (>= 0.3.0)
activemodel (4.2.8)
activesupport (= 4.2.8)
builder (~> 3.1)
activerecord (4.2.8)
activemodel (= 4.2.8)
activesupport (= 4.2.8)
arel (~> 6.0)
activerecord-session_store (1.1.3)
actionpack (>= 4.0)
activerecord (>= 4.0)
multi_json (~> 1.11, >= 1.11.2)
rack (>= 1.5.2, < 3)
railties (>= 4.0)
activesupport (4.2.8)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0)
airbrussh (1.4.1)
sshkit (>= 1.6.1, != 1.7.0)
arel (6.0.4)
ast (2.4.2)
attr_required (1.0.1)
bcrypt (3.1.19)
better_errors (2.2.0)
coderay (>= 1.0.0)
erubis (>= 2.6.6)
rack (>= 0.9.0)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
blockspring (0.1.4)
rest-client (> 1.6.7)
builder (3.2.4)
cairo (1.17.12)
native-package-installer (>= 1.0.3)
pkg-config (>= 1.2.2)
red-colors
cairo-gobject (4.1.8)
cairo (>= 1.16.2)
glib2 (= 4.1.8)
capistrano (3.17.3)
airbrussh (>= 1.0.0)
i18n
rake (>= 10.0.0)
sshkit (>= 1.9.0)
capistrano-bundler (2.1.0)
capistrano (~> 3.1)
capistrano-faster-assets (1.1.0)
capistrano (>= 3.1)
capistrano-rails (1.6.3)
capistrano (~> 3.1)
capistrano-bundler (>= 1.1, < 3)
capybara (2.15.1)
addressable
mini_mime (>= 0.1.3)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
capybara-email (3.0.2)
capybara (>= 2.4, < 4.0)
mail
carrierwave (1.3.3)
activemodel (>= 4.0.0)
activesupport (>= 4.0.0)
mime-types (>= 1.16)
ssrf_filter (~> 1.0, < 1.1.0)
carrierwave-imageoptimizer (1.6.0)
carrierwave (>= 0.8, < 3.0)
image_optimizer (~> 1.6)
caxlsx (3.4.1)
htmlentities (~> 4.3, >= 4.3.4)
marcel (~> 1.0)
nokogiri (~> 1.10, >= 1.10.4)
rubyzip (>= 1.3.0, < 3)
childprocess (3.0.0)
chronic (0.10.2)
cliver (0.3.2)
coderay (1.1.3)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
coveralls (0.7.1)
multi_json (~> 1.3)
rest-client
simplecov (>= 0.7)
term-ansicolor
thor
crack (0.4.5)
rexml
crass (1.0.6)
css_parser (1.12.0)
addressable
cucumber (7.1.0)
builder (~> 3.2, >= 3.2.4)
cucumber-core (~> 10.1, >= 10.1.0)
cucumber-create-meta (~> 6.0, >= 6.0.1)
cucumber-cucumber-expressions (~> 14.0, >= 14.0.0)
cucumber-gherkin (~> 22.0, >= 22.0.0)
cucumber-html-formatter (~> 17.0, >= 17.0.0)
cucumber-messages (~> 17.1, >= 17.1.1)
cucumber-wire (~> 6.2, >= 6.2.0)
diff-lcs (~> 1.4, >= 1.4.4)
mime-types (~> 3.3, >= 3.3.1)
multi_test (~> 0.1, >= 0.1.2)
sys-uname (~> 1.2, >= 1.2.2)
cucumber-core (10.1.1)
cucumber-gherkin (~> 22.0, >= 22.0.0)
cucumber-messages (~> 17.1, >= 17.1.1)
cucumber-tag-expressions (~> 4.1, >= 4.1.0)
cucumber-create-meta (6.0.4)
cucumber-messages (~> 17.1, >= 17.1.1)
sys-uname (~> 1.2, >= 1.2.2)
cucumber-cucumber-expressions (14.0.0)
cucumber-gherkin (22.0.0)
cucumber-messages (~> 17.1, >= 17.1.1)
cucumber-html-formatter (17.0.0)
cucumber-messages (~> 17.1, >= 17.1.0)
cucumber-messages (17.1.1)
cucumber-rails (1.4.0)
capybara (>= 1.1.2)
cucumber (>= 1.2.0)
nokogiri (>= 1.5.0)
rails (>= 3.0.0)
cucumber-tag-expressions (4.1.0)
cucumber-wire (6.2.1)
cucumber-core (~> 10.1, >= 10.1.0)
cucumber-cucumber-expressions (~> 14.0, >= 14.0.0)
daemon-spawn (0.4.2)
daemons (1.4.1)
database_cleaner (1.99.0)
debug_inspector (1.1.0)
diff-lcs (1.5.0)
diffy (3.4.2)
digest (3.1.1)
docile (1.4.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
erubis (2.7.0)
execjs (2.8.1)
factory_girl (4.9.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.9.0)
factory_girl (~> 4.9.0)
railties (>= 3.0.0)
faraday (1.10.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
ffi (1.15.5)
fiddle (1.1.1)
forgery (0.8.1)
formatador (1.1.0)
gdk_pixbuf2 (4.1.8)
gio2 (= 4.1.8)
geocoder (1.8.1)
gherkin3 (3.1.2)
gio2 (4.1.8)
fiddle
gobject-introspection (= 4.1.8)
glib2 (4.1.8)
native-package-installer (>= 1.0.3)
pkg-config (>= 1.3.5)
globalid (0.4.2)
activesupport (>= 4.2.0)
gobject-introspection (4.1.8)
glib2 (= 4.1.8)
guard (2.18.0)
formatador (>= 0.2.4)
listen (>= 2.7, < 4.0)
lumberjack (>= 1.0.12, < 2.0)
nenv (~> 0.1)
notiffany (~> 0.0)
pry (>= 0.13.0)
shellany (~> 0.0)
thor (>= 0.18.1)
guard-compat (1.2.1)
guard-cucumber (3.0.0)
cucumber (>= 3.1)
nenv (>= 0.1)
guard-rspec (4.7.3)
guard (~> 2.1)
guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0)
haml (6.1.1)
temple (>= 0.8.2)
thor
tilt
haml-lint (0.999.999)
haml_lint
haml_lint (0.45.0)
haml (>= 4.0, < 6.2)
parallel (~> 1.10)
rainbow
rubocop (>= 0.50.0)
sysexits (~> 1.1)
hashdiff (1.0.1)
hashie (5.0.0)
htmlentities (4.3.4)
http-accept (1.7.0)
http-cookie (1.0.5)
domain_name (~> 0.5)
http_accept_language (2.1.1)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
ianfleeton-paypal-express (0.8.7)
activesupport (>= 2.3, < 8)
attr_required (~> 1.0)
rest-client (~> 2.0)
image_optimizer (1.9.0)
io-wait (0.3.0)
jwt (2.7.1)
kgio (2.11.4)
launchy (2.5.2)
addressable (~> 2.8)
letter_opener (1.8.1)
launchy (>= 2.2, < 3)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
loofah (2.21.3)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
lumberjack (1.2.8)
mail (2.8.1)
mini_mime (>= 0.1.1)
net-imap
net-pop
net-smtp
marcel (1.0.2)
matrix (0.4.2)
meta_request (0.7.4)
rack-contrib (>= 1.1, < 3)
railties (>= 3.0.0, < 7.1)
method_source (1.0.0)
mime-types (3.4.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2023.0218.1)
mini_magick (4.12.0)
mini_mime (1.1.2)
mini_portile2 (2.6.1)
minitest (5.15.0)
mocha (2.0.4)
ruby2_keywords (>= 0.0.5)
multi_json (1.15.0)
multi_test (0.1.2)
multi_xml (0.6.0)
multipart-post (2.3.0)
native-package-installer (1.1.8)
nenv (0.3.0)
net-imap (0.2.2)
digest
net-protocol
strscan
net-pop (0.1.2)
net-protocol
net-protocol (0.1.2)
io-wait
timeout
net-scp (4.0.0)
net-ssh (>= 2.6.5, < 8.0.0)
net-smtp (0.3.0)
digest
net-protocol
timeout
net-ssh (4.1.0)
netrc (0.11.0)
nokogiri (1.12.5)
mini_portile2 (~> 2.6.1)
racc (~> 1.4)
notiffany (0.1.3)
nenv (~> 0.1)
shellany (~> 0.0)
oauth (0.6.2)
snaky_hash (~> 2.0)
version_gem (~> 1.1)
oauth2 (1.4.11)
faraday (>= 0.17.3, < 3.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 4)
parallel (1.23.0)
parser (3.2.2.3)
ast (~> 2.4.1)
racc
pg (0.21.0)
pkg-config (1.5.2)
poltergeist (1.18.1)
capybara (>= 2.1, < 4)
cliver (~> 0.3.1)
websocket-driver (>= 0.2.0)
premailer (1.15.0)
addressable
css_parser (>= 1.6.0)
htmlentities (>= 4.0.0)
premailer-rails (1.12.0)
actionmailer (>= 3)
net-smtp
premailer (~> 1.7, >= 1.7.9)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
public_suffix (4.0.7)
racc (1.7.1)
rack (1.6.13)
rack-contrib (1.8.0)
rack (~> 1.4)
rack-mini-profiler (3.0.0)
rack (>= 1.2.0)
rack-protection (2.2.4)
rack
rack-test (0.6.3)
rack (>= 1.0)
rails (4.2.8)
actionmailer (= 4.2.8)
actionpack (= 4.2.8)
actionview (= 4.2.8)
activejob (= 4.2.8)
activemodel (= 4.2.8)
activerecord (= 4.2.8)
activesupport (= 4.2.8)
bundler (>= 1.3.0, < 2.0)
railties (= 4.2.8)
sprockets-rails
rails-deprecated_sanitizer (1.0.4)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.9)
activesupport (>= 4.2.0, < 5.0)
nokogiri (~> 1.6)
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.5.0)
loofah (~> 2.19, >= 2.19.1)
rails-i18n (4.0.9)
i18n (~> 0.7)
railties (~> 4.0)
rails_12factor (0.0.3)
rails_serve_static_assets
rails_stdout_logging
rails_serve_static_assets (0.0.5)
rails_stdout_logging (0.0.5)
railties (4.2.8)
actionpack (= 4.2.8)
activesupport (= 4.2.8)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rainbow (3.1.1)
raindrops (0.20.1)
rake (12.3.3)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
red-colors (0.3.0)
matrix
redcarpet (3.6.0)
redis (4.8.1)
regexp_parser (2.8.1)
responders (2.4.1)
actionpack (>= 4.2.0, < 6.0)
railties (>= 4.2.0, < 6.0)
rest-client (2.1.0)
http-accept (>= 1.7.0, < 2.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
rexml (3.2.5)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.5)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-rails (4.1.2)
actionpack (>= 4.2)
activesupport (>= 4.2)
railties (>= 4.2)
rspec-core (~> 3.10)
rspec-expectations (~> 3.10)
rspec-mocks (~> 3.10)
rspec-support (~> 3.10)
rspec-support (3.12.1)
rsvg2 (4.1.8)
cairo-gobject (= 4.1.8)
gdk_pixbuf2 (= 4.1.8)
rubocop (1.28.2)
parallel (~> 1.10)
parser (>= 3.1.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml
rubocop-ast (>= 1.17.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.17.0)
parser (>= 3.1.1.0)
ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5)
ruby_dep (1.4.0)
rubyzip (2.3.2)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-json-vars (0.3.3)
sass (>= 3.1)
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)
railties (>= 4.0.0)
sassc (>= 2.0)
sprockets (> 3.0)
sprockets-rails
tilt
selenium-webdriver (3.142.7)
childprocess (>= 0.5, < 4.0)
rubyzip (>= 1.2.2)
shellany (0.0.1)
sidekiq (5.2.8)
connection_pool (~> 2.2, >= 2.2.2)
rack (< 2.1.0)
rack-protection (>= 1.5.0)
redis (>= 3.3.5, < 5)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
sitemap_generator (6.3.0)
builder (~> 3.0)
snaky_hash (2.0.1)
hashie
version_gem (~> 1.1, >= 1.1.1)
sprockets (4.1.1)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.2.2)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sshkit (1.21.5)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
ssrf_filter (1.0.8)
strscan (3.0.6)
sync (0.5.0)
sys-uname (1.2.3)
ffi (~> 1.1)
sysexits (1.2.0)
temple (0.10.2)
term-ansicolor (1.7.1)
tins (~> 1.0)
thin (1.8.2)
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
rack (>= 1, < 3)
thor (1.2.2)
thread_safe (0.3.6)
tilt (2.2.0)
timeout (0.4.0)
tins (1.32.1)
sync
tzinfo (1.2.11)
thread_safe (~> 0.1)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
unicode-display_width (2.4.2)
unicorn (6.1.0)
kgio (~> 2.6)
raindrops (~> 0.7)
version_gem (1.1.3)
webmock (3.18.1)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
xpath (2.1.0)
nokogiri (~> 1.3)
PLATFORMS
ruby
DEPENDENCIES
activerecord-session_store
better_errors (= 2.2.0)
bikecollectives_core!
binding_of_caller
bumbleberry!
capistrano (~> 3.1)
capistrano-faster-assets (~> 1.0)
capistrano-rails (~> 1.1)
capybara (= 2.15.1)
capybara-email
carrierwave
carrierwave-imageoptimizer
coveralls
cucumber
cucumber-core
cucumber-rails
daemon-spawn
daemons
database_cleaner
eventmachine!
factory_girl_rails
geocoder
gherkin3 (>= 3.1.0)
guard-cucumber
guard-rspec
haml
haml-lint
ianfleeton-paypal-express
launchy
letter_opener
lingua_franca!
marmara!
meta_request
mini_magick
mocha
net-ssh (= 4.1.0)
nokogiri
pg (= 0.21.0)
poltergeist
premailer-rails
rack-mini-profiler
rails (= 4.2.8)
rails_12factor
rake (= 12.3.3)
redcarpet
rspec
rspec-rails
rubocop
ruby_dep (= 1.4)
sass
sass-json-vars
sass-rails
selenium-webdriver
sidekiq
simplecov
sitemap_generator
sorcery!
thin
to_spreadsheet!
tzinfo-data
uglifier (>= 1.3.0)
unicorn
wdm (>= 0.1.0)
webmock
win32console
BUNDLED WITH
1.17.3

526
README.md
View File

@ -1,152 +1,374 @@
# Bike!Bike! # # Bike!Bike! #
| Environment | Build Status | | Environment | Build Status |
| ----------- |:------------:| | ----------- |:------------:|
| Development | [![Development Build Status](https://travis-ci.org/bikebike/BikeBike.svg?branch=development)](https://travis-ci.org/bikebike/BikeBike) | | Development | [![Development Build Status](https://travis-ci.org/bikebike/BikeBike.svg?branch=development)](https://travis-ci.org/bikebike/BikeBike) |
| Production | [![Production Build Status](https://travis-ci.org/bikebike/BikeBike.svg?branch=master)](https://travis-ci.org/bikebike/BikeBike) | | Production | It works with this Fork! |
This is the repository for the Bike!Bike! website. It can be found in development at [preview.bikebike.org](https://preview-en.bikebike.org/) and in production at [bikebike.org](https://bikebike.org/) ## About this Fork
Feel free to clone or fork the repository any time to start working on new features or fixes. To get help create an issue or contact Godwin: `goodgodwin` `@` `hotmail.com` any time. The Tech group for BikeBike!Everywhere! decided to utilize this conferencing/scheduling software for the next BikeBike.
![Screenshot of Bike!Bike!](https://workbench.bikecollectives.org/apps/bikebike/screenshots/application/home/3/desktop.png) This repository creates a test environment so that we can test/fix issues before manually committing them to the live site.
## Technologies ## Instructions can be found in docker-compose.yml, and docker-compose.build.
* [Ruby 2.3.0][1] ### Install git-lfs
* [Rails 4.2.0][2] _([Project to upgrade to Rails 5](https://github.com/orgs/bikebike/projects/13))_
* [PostgreSQL][3] This repository utilizes git-lfs. You will want git-lfs installed:
* [HAML][4]
* [SCSS][5] `apt-get install git-lfs`
* [NGinx][6] _([We may switch to Caddy](https://github.com/bikebike/bikecollectives_core/issues/1))_
* [DigitalOcean][7] _([We may switch to Linode](https://github.com/bikebike/bikecollectives_core/issues/2))_ then
[1]: http://www.ruby-lang.org/en/ `git lfs pull`
[2]: http://rubyonrails.org/
[3]: http://www.postgresql.org/ You can learn more about git-lfs commands at https://sabicalija.github.io/git-lfs-intro/
[4]: http://haml.info/
[5]: http://sass-lang.com/ ### About that letsencrypt network in docker-compose.yml
[6]: https://www.nginx.com/
[7]: https://digitalocean.com This network provides a nginx proxy and an automatic generation of letsencrypt certificates.
#### The bike_bike_advanced_environment file
## Internal Gems ##
We will make a commitment to extract any functionality that makes sense to do so, into separate gems in order to share functionality with others, with our other projects (such as bikecollectives.org), and to enable easier collaboration amongst ourselves. This file allows you to insert custom environmental variables, but primarily so that [ACME Companion](https://github.com/nginx-proxy/acme-companion) can be utilized to automate the creation, renewal and use of SSL certificates for proxied Docker containers through the ACME protocol. This is useful to seamlessly handle the secure translation urls. The example variables below communicate to an available external acme (letsencrypt) network to properly setup this proxied environment.
It is recommended that you at least use also clone `bikecollectives_core` into you workspace. To override the gem location execute: ```
VIRTUAL_HOST=bb.bikelover.org,en.bikelover.org,en.bb.bikelover.org,es.bb.bikelover.org,fr.bb.bikelover.org
```bash LETSENCRYPT_HOST=bb.bikelover.org,en.bikelover.org,en.bb.bikelover.org,es.bb.bikelover.org,fr.bb.bikelover.org
bundle config local.bikecollectives_core PATH_TO/bikecollectives_core LETSENCRYPT_EMAIL=bike@bikelover.org
``` VIRTUAL_PORT=3000
```
Here is a list of the gems we have created so far, if you are a collaborator on this project you may need to become a collaborator on these gems as well. Don't hesitate to make a request, it won't be denied: This is an example docker-compose.yml file handling the letsencrypt network.
### Bike Collectives Core ### <details>
<summary>
[Bike Collectives Core](https://github.com/bikebike/bikecollectives_core) is where models, migrations, and some common controllers and helpers live. This Gem is shared between [Bike Collectives](https://github.com/bikebike/bikecollectives) and [Bike Collectives Workbench](https://github.com/bikebike/bikecollectives_workbench).
```
### Lingua Franca ### docker-compose.yml (acme-companion & nginx-proxy)
```
[Lingua Franca](https://github.com/lingua-franca/lingua_franca) provides an easy way to include translatable content and provides a user interface for translators to provide translations. See [Translations](#translations) for best practices on the Bike!Bike! website.
</summary>
### Bumbleberry ###
[Bumbleberry](https://github.com/bumbleberry/bumbleberry) provides cross-browser support with little effort and minimum file sizes. Basically it creates a different stylesheet for every known browser and only includes supported rules for each using information obtained from [caniuse.com](caniuse.com). ```
version: '3'
## Github Workflow ## # LetsEncrypt
If you are a git wiz, feel free to adjust the steps below slightly, otherwise follow these steps until you are familiar enough to stray. What should remain constant is that we need to branch, code review, and merge with master. # If you need a custome nginx.conf, remember to copy it over
1. Before you start working on a new feature, start working on a new branch (alternatively you can fork): `git checkout -b myname_new_feature` services:
1. Write your new feature
1. Add tests and execute them using `bundle exec i18n` letsencrypt:
1. Make any adjustments, make sure you have included comments and abided other coding conventions image: nginxproxy/acme-companion
1. Check your git status to make sure you are on the correct branch and have any new files to add: `git status` container_name: letsencrypt
1. Add any new files using: `git add [myfile]` #volumes_from:
1. Commit your changes: `git commit -am 'My commit message'` # - nginx-proxy
1. Switch back to the development branch and pull the latest: `git checkout master && git pull` volumes:
1. Switch back to your branch: `git checkout myname_new_feature` - certs:/etc/nginx/certs:rw
1. If there were any changes, rebase. This merges in the new code with your new code: `git rebase -i origin/development` - acme:/etc/acme.sh
1. Push your changes: `git push origin myname_new_feature` - vhost:/etc/nginx/vhost.d
1. Make a pull request and wait for your code to be reviewed - html:/usr/share/nginx/html
1. If any changes are required, make them commit your changes, and rebase again. This time you need to make sure that you squash your commits (makes sure you only add one commit in the end). Where you see your commit message, change 'pick' to 'fixup' or 'f'. - /var/run/docker.sock:/var/run/docker.sock:ro
1. Push your code again and repeat 12 and 13 until your code gets merged with development environment:
1. Once your code is in development it will be released to our development site, once new translations are added and the site is manually tested it will be moved to master and the production site - NGINX_PROXY_CONTAINER=nginx-proxy
#network_mode: "bridge"
## Deployment Process ## logging:
Please note, we currently don't have this process set up, we're working to get here. driver: "json-file"
options:
1. Write code and get it pulled into master max-size: "10m"
2. Your changes will be automatically be deployed to our preview site max-file: "3"
3. Your changes will be tested there, if tests fail deployers will be notified restart: always
4. Once that deployment process completes and tests pass, translators will be notified if there are new translations networks:
4. Once translators have completed translations, translations will be committed to master and your changes will be deployed to production letsencrypt:
nginx-proxy:
## Translations ## image: nginxproxy/nginx-proxy
container_name: nginx-proxy
Translating our site into multiple languages is a key part of opening it up to the world. When coding, never include any English text as in a string or Haml. Instead, we shall always use the underscore helper method `_`. The method takes a translation key and some optional parameters. volumes:
- conf:/etc/nginx/conf.d
All translation is done in a collaborative, volunteer based system on the site itself, even the English text. If a user has sufficient permissions, the underscore method will produce highlighted text which can be edited directly by the user. - vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
The method can be used as follows: - certs:/etc/nginx/certs:ro
- /var/run/docker.sock:/tmp/docker.sock:ro
```haml ports:
%h1=_'basename.my_title' - "80:80"
%p=_'basename.my_key', :paragraph - "443:443"
%button=_'basename.click_me' logging:
``` driver: "json-file"
options:
Assuming none of the keys map to translations, this will be rendered into the following HTML: max-size: "10m"
max-file: "3"
```html restart: always
<h1> networks:
Lorem ipsum dolor sit amet letsencrypt:
</h1>
<p> volumes:
Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Proin eget tortor risus. Donec sollicitudin molestie malesuada. Donec rutrum congue leo eget malesuada. certs:
</p> vhost:
html:
<button> conf:
click me acme:
</button>
``` networks:
letsencrypt:
By default, the key will be translated using the last key part ('click me' in this example), however if a context is provided, some appropriate lorem ipsum text. Available contexts are: external: true
````
* `title` (alias: `t`): title text, a few words in upper case
* `word` (alias: `words`, `w`): A word, if a second parameter is provided a numbr of words will be rendered (for example `_'key',:w,3`) </details>
* `sentence` (alias: `sentences`, `s`): A sentence or multiple sentence
* `paragraph` (alias: `p`): A paragraph ### Commonly used environmental variables in .env
If actual translations are not provided by the time the code hits production, fatals will occur. ```
RAILS_ENV={production | development | customized environment in config/environments}
### Entering translations PORT={usually 3000}
SMTP_ADDRESS={your SMTP server address}
Translations can be provided directly by editing [`en.yml`](https://github.com/bikebike/BikeBike/blob/master/config/locales/en.yml) but will also be directly using the [workbench](https://github.com/bikebike/bikecollectives_workbench): SMTP_DOMAIN={The domain you want to link back in emails, usually the website itself, but not any translation subdomains}
SMTP_PORT={465 | ..}
![Screenshot of the Bike Collectives Workbench](https://i.imgur.com/y8Ezjeg.png) SMTP_USER_NAME={SMTP username}
SMTP_PASSWORD={SMTP password}
### Collecting translations SMTP_SSL={true | false}
ADMIN_EMAIL={administrator email address}
Translations, along with screenshots and HTML page captures are collected during testing so that the workbench will have up to date translations and context for each to make it easier for translators to provide relevant translations. To collect these translations yourself, execute `rake i18n`. DEFAULT_URL={the website itself}
```
## Testing Practices ##
### After successful installation
Our focus will be on integration testing using Capybara. While testing the app records all translations that it finds, whether or not they exist, and which pages that they were found on.
There isn't much to do until the first conference is created. But you will need an adminstrator to make that happen.
Before commiting you shuold always run:
First create a user for yourself at /user . If you properly setup SMTP via docker, you will receive a confirmation email, which allows you to setup a session on your respective browser.
```bash
bundle exec rake cucumber:run Then go to the database container (db), and utilizing psql, update your user.
```
`UPDATE users SET role = 'administrator' WHERE firstname = 'Jonathan Rosenbaum';`
and:
Now go to /conferences , create your first conference, and the fun begins!
```bash
bundle exec rake i18n The commandline psql interacts with the database with 'strict' sql statements, so use single quotes around strings, not double quotes, and all should be good.
```
Here's a good link to bring you up to speed with the power of psql: [https://phili.pe/posts/postgresql-on-the-command-line/](https://phili.pe/posts/postgresql-on-the-command-line/)
The former is going to be faster but does not perform checks for untranslated content, it is recommneded that you run this regularily while developing while running the `i18n` check will ensure that you have not missed translations.
### Job Scheduler for caniuse.js
If you are creating any new content you will also want to add a new feature or scenario to ensure the new translations are picked up.
[Caniuse.js](caniuse.js) uses browserslist to query the caniuse-lite database. This is the substitute program for the now defunct Bumbleberry. Ofelia is used as an independent scheduler, and ofelia labels in [services](docker-compose.yml) establish the job requirements.
<details>
<summary>
```
docker-compose.yml for Ofelia job scheduler
```
</summary>
```
# This service provides ofelia, which is a job scheduler (cron).
#
# There should be at least on job in one of the services to make this
# meaningfull to run.
#
# It is accessible everywhere since it is bound to the docker socket.
# Cron jobs can be conveniently created with labels.
#
# https://github.com/mcuadros/ofelia
#
# When you add/change a cron job simply -
# docker compose restart
services:
ofelia:
container_name: ofelia
image: mcuadros/ofelia:latest
command: daemon --docker
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
```
</details>
### Production and Development mode
You may easily switch between the production and development environment in the .env file.
`RAILS_ENV=production`
One good reason for doing this is that some system administration tasks are handled differently in production. For instance, mail is delayed in production.
Realize you can always do things in the container .. the commands without docker-compose, or automate it all with a docker-compose script:
`docker-compose exec bikebike /bin/bash`
#### From production to development after changing .env
```
docker-compose down
docker-compose up -d
rake assets:clobber
rake assets:precompile
```
#### From development to production after changing .env
```
docker-compose down
docker-compose up -d
rake assets:clobber
rake assets:precompile
rake db:sessions:clear
docker-compose restart bikebike
```
## From bikebike/bikebike
This is the repository for the Bike!Bike! website. It can be found in development at [preview.bikebike.org](https://preview-en.bikebike.org/) and in production at [bikebike.org](https://bikebike.org/)
Feel free to clone or fork the repository any time to start working on new features or fixes. To get help create an issue or contact Godwin: `goodgodwin` `@` `hotmail.com` any time.
![Screenshot of Bike!Bike!](https://workbench.bikecollectives.org/apps/bikebike/screenshots/application/home/3/desktop.png)
## Technologies ##
* [Ruby 2.3.0][1]
* [Rails 4.2.0][2] _([Project to upgrade to Rails 5](https://github.com/orgs/bikebike/projects/13))_
* [PostgreSQL][3]
* [HAML][4]
* [SCSS][5]
* [NGinx][6] _([We may switch to Caddy](https://github.com/bikebike/bikecollectives_core/issues/1))_
* [DigitalOcean][7] _([We may switch to Linode](https://github.com/bikebike/bikecollectives_core/issues/2))_
[1]: http://www.ruby-lang.org/en/
[2]: http://rubyonrails.org/
[3]: http://www.postgresql.org/
[4]: http://haml.info/
[5]: http://sass-lang.com/
[6]: https://www.nginx.com/
[7]: https://digitalocean.com
## Internal Gems ##
We will make a commitment to extract any functionality that makes sense to do so, into separate gems in order to share functionality with others, with our other projects (such as bikecollectives.org), and to enable easier collaboration amongst ourselves.
It is recommended that you at least use also clone `bikecollectives_core` into you workspace. To override the gem location execute:
```bash
bundle config local.bikecollectives_core PATH_TO/bikecollectives_core
```
Here is a list of the gems we have created so far, if you are a collaborator on this project you may need to become a collaborator on these gems as well. Don't hesitate to make a request, it won't be denied:
### Bike Collectives Core ###
[Bike Collectives Core](https://github.com/bikebike/bikecollectives_core) is where models, migrations, and some common controllers and helpers live. This Gem is shared between [Bike Collectives](https://github.com/bikebike/bikecollectives) and [Bike Collectives Workbench](https://github.com/bikebike/bikecollectives_workbench).
### Lingua Franca ###
[Lingua Franca](https://github.com/lingua-franca/lingua_franca) provides an easy way to include translatable content and provides a user interface for translators to provide translations. See [Translations](#translations) for best practices on the Bike!Bike! website.
### Bumbleberry ###
[Bumbleberry](https://github.com/bumbleberry/bumbleberry) provides cross-browser support with little effort and minimum file sizes. Basically it creates a different stylesheet for every known browser and only includes supported rules for each using information obtained from [caniuse.com](caniuse.com).
## Github Workflow ##
If you are a git wiz, feel free to adjust the steps below slightly, otherwise follow these steps until you are familiar enough to stray. What should remain constant is that we need to branch, code review, and merge with master.
1. Before you start working on a new feature, start working on a new branch (alternatively you can fork): `git checkout -b myname_new_feature`
1. Write your new feature
1. Add tests and execute them using `bundle exec i18n`
1. Make any adjustments, make sure you have included comments and abided other coding conventions
1. Check your git status to make sure you are on the correct branch and have any new files to add: `git status`
1. Add any new files using: `git add [myfile]`
1. Commit your changes: `git commit -am 'My commit message'`
1. Switch back to the development branch and pull the latest: `git checkout master && git pull`
1. Switch back to your branch: `git checkout myname_new_feature`
1. If there were any changes, rebase. This merges in the new code with your new code: `git rebase -i origin/development`
1. Push your changes: `git push origin myname_new_feature`
1. Make a pull request and wait for your code to be reviewed
1. If any changes are required, make them commit your changes, and rebase again. This time you need to make sure that you squash your commits (makes sure you only add one commit in the end). Where you see your commit message, change 'pick' to 'fixup' or 'f'.
1. Push your code again and repeat 12 and 13 until your code gets merged with development
1. Once your code is in development it will be released to our development site, once new translations are added and the site is manually tested it will be moved to master and the production site
## Deployment Process ##
Please note, we currently don't have this process set up, we're working to get here.
1. Write code and get it pulled into master
2. Your changes will be automatically be deployed to our preview site
3. Your changes will be tested there, if tests fail deployers will be notified
4. Once that deployment process completes and tests pass, translators will be notified if there are new translations
4. Once translators have completed translations, translations will be committed to master and your changes will be deployed to production
## Translations ##
Translating our site into multiple languages is a key part of opening it up to the world. When coding, never include any English text as in a string or Haml. Instead, we shall always use the underscore helper method `_`. The method takes a translation key and some optional parameters.
All translation is done in a collaborative, volunteer based system on the site itself, even the English text. If a user has sufficient permissions, the underscore method will produce highlighted text which can be edited directly by the user.
The method can be used as follows:
```haml
%h1=_'basename.my_title'
%p=_'basename.my_key', :paragraph
%button=_'basename.click_me'
```
Assuming none of the keys map to translations, this will be rendered into the following HTML:
```html
<h1>
Lorem ipsum dolor sit amet
</h1>
<p>
Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Vivamus magna justo, lacinia eget consectetur sed, convallis at tellus. Proin eget tortor risus. Donec sollicitudin molestie malesuada. Donec rutrum congue leo eget malesuada.
</p>
<button>
click me
</button>
```
By default, the key will be translated using the last key part ('click me' in this example), however if a context is provided, some appropriate lorem ipsum text. Available contexts are:
* `title` (alias: `t`): title text, a few words in upper case
* `word` (alias: `words`, `w`): A word, if a second parameter is provided a numbr of words will be rendered (for example `_'key',:w,3`)
* `sentence` (alias: `sentences`, `s`): A sentence or multiple sentence
* `paragraph` (alias: `p`): A paragraph
If actual translations are not provided by the time the code hits production, fatals will occur.
### Entering translations
Translations can be provided directly by editing [`en.yml`](https://github.com/bikebike/BikeBike/blob/master/config/locales/en.yml) but will also be directly using the [workbench](https://github.com/bikebike/bikecollectives_workbench):
![Screenshot of the Bike Collectives Workbench](https://i.imgur.com/y8Ezjeg.png)
### Collecting translations
Translations, along with screenshots and HTML page captures are collected during testing so that the workbench will have up to date translations and context for each to make it easier for translators to provide relevant translations. To collect these translations yourself, execute `rake i18n`.
## Testing Practices ##
Our focus will be on integration testing using Capybara. While testing the app records all translations that it finds, whether or not they exist, and which pages that they were found on.
Before commiting you shuold always run:
```bash
bundle exec rake cucumber:run
```
and:
```bash
bundle exec rake i18n
```
The former is going to be faster but does not perform checks for untranslated content, it is recommneded that you run this regularily while developing while running the `i18n` check will ensure that you have not missed translations.
If you are creating any new content you will also want to add a new feature or scenario to ensure the new translations are picked up.

View File

@ -0,0 +1,4 @@
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .scss
//= link_directory ../fonts

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
body{background-color:#fff;color:#333;font-family:verdana, arial, helvetica, sans-serif;font-size:13px;line-height:18px}p,ol,ul,td{font-family:verdana, arial, helvetica, sans-serif;font-size:13px;line-height:18px}pre{background-color:#eee;padding:10px;font-size:11px}a{color:#000}a:visited{color:#666}a:hover{color:#fff;background-color:#000}div.field,div.actions{margin-bottom:10px}#notice{color:green}.field_with_errors{padding:2px;background-color:red;display:table}#error_explanation{width:450px;border:2px solid red;padding:7px;padding-bottom:0;margin-bottom:20px;background-color:#f0f0f0}#error_explanation h2{text-align:left;font-weight:bold;padding:5px 5px 5px 15px;font-size:12px;margin:-7px;margin-bottom:0px;background-color:#c00;color:#fff}#error_explanation ul li{font-size:12px;list-style:square}

View File

@ -1,3 +1,5 @@
require 'net/https'
class ApplicationController < BaseController class ApplicationController < BaseController
protect_from_forgery with: :exception, except: [:do_confirm, :js_error, :admin_update] protect_from_forgery with: :exception, except: [:do_confirm, :js_error, :admin_update]
@ -6,6 +8,19 @@ class ApplicationController < BaseController
helper_method :protect, :policies helper_method :protect, :policies
RECAPTCHA_MINIMUM_SCORE = 0.5
def verify_recaptcha?(token, recaptcha_action)
recaptcha_secret_key = ENV['RECAPTCHA_SECRET_KEY']
uri = URI.parse("https://www.google.com/recaptcha/api/siteverify?secret=#{recaptcha_secret_key}&response=#{token}")
response = Net::HTTP.get_response(uri)
json = JSON.parse(response.body)
# json['success'] && json['score'] > RECAPTCHA_MINIMUM_SCORE && json['action'] == recaptcha_action
puts json.inspect
json['success'] && json['score'] > RECAPTCHA_MINIMUM_SCORE
end
def default_url_options def default_url_options
{ host: "#{request.protocol}#{request.host_with_port}", trailing_slash: true } { host: "#{request.protocol}#{request.host_with_port}", trailing_slash: true }
end end
@ -101,6 +116,7 @@ class ApplicationController < BaseController
end end
def confirmation_sent(user) def confirmation_sent(user)
template = 'login_confirmation_sent' template = 'login_confirmation_sent'
@page_title ||= 'page_titles.403.Please_Check_Email' @page_title ||= 'page_titles.403.Please_Check_Email'
@ -213,7 +229,7 @@ class ApplicationController < BaseController
end end
def contact_send def contact_send
email_list = ['Godwin <goodgodwin@hotmail.com>'] email_list = [ENV['ADMIN_EMAIL']]
if params[:reason] == 'conference' && logged_in? if params[:reason] == 'conference' && logged_in?
@ -232,20 +248,23 @@ class ApplicationController < BaseController
request_info['env'][key.to_s] = value.to_s request_info['env'][key.to_s] = value.to_s
end end
send_delayed_mail(:contact, if !(params[:subject] =~ /^\s*[a-z]{10}\s*$/i)
current_user || params[:email],
params[:subject],
params[:message],
email_list
)
send_delayed_mail(:contact_details, send_delayed_mail(:contact,
current_user || params[:email], current_user || params[:email],
params[:subject], params[:subject],
params[:message], params[:message],
request_info, email_list
params )
)
send_delayed_mail(:contact_details,
current_user || params[:email],
params[:subject],
params[:message],
request_info,
params
)
end
redirect_to contact_sent_path redirect_to contact_sent_path
end end
@ -638,6 +657,14 @@ class ApplicationController < BaseController
# send the confirmation email and make sure it get sent as quickly as possible # send the confirmation email and make sure it get sent as quickly as possible
def send_confirmation(confirmation) def send_confirmation(confirmation)
# puts lookup_context.find_all(params[:action], params[:controller]).inspect
unless verify_recaptcha?(params[:recaptcha_token], 'sign_in')
flash.now[:error] = 'recaptcha.errors.verification_failed'
return render 'about'
end
send_mail(:email_confirmation, confirmation.id) send_mail(:email_confirmation, confirmation.id)
end end

View File

@ -2,6 +2,37 @@ require 'geocoder/calculations'
require 'rest_client' require 'rest_client'
require 'registration_controller_helper' require 'registration_controller_helper'
module RegistrationSteps
def available_steps(registration = self)
if conference.city_name.present? && Conference.find_by(id: registration.conference_id).city_id == 433
all_southpole_steps = [
:policy, # agree to the policy
:name, # enter your name
:languages, # select spoken languages
:org_member, # Do you work for or volunteer with a bike collective?
:org_location, # Where is your collective located?
:org_location_confirm, # Confirm your location
:org_non_member_interest, # What is your interest in attending Bike!Bike!?
:org_select, # Which organization in [city] are you associated with?
:org_create_name, # What is the name of your organization?
:org_create_address, # Where in [city] is your organization located?
:org_create_email, # What is the organization's email address
:org_create_mailing_address, # How can we contact your organization by snail mail?
:housing_arrival_date, # When will you be arriving in [city]?
:housing_departure_date, # When are you planning to leave [city]?
:review
]
available = all_southpole_steps.select { |step| send("#{step}_available?", registration) }
else available = RegistrationSteps.all_registration_steps.select { |step| send("#{step}_available?", registration) }
end
return available
end
end
class ConferencesController < ApplicationController class ConferencesController < ApplicationController
include RegistrationControllerHelper include RegistrationControllerHelper
@ -158,6 +189,7 @@ class ConferencesController < ApplicationController
helper_method :registration_complete? helper_method :registration_complete?
def registration_steps(conference = nil) def registration_steps(conference = nil)
File.write('testingdebug', "in registration_steps (conferences_controller_\n", mode: 'a')
conference ||= @this_conference || @conference conference ||= @this_conference || @conference
status = conference.registration_status status = conference.registration_status
@ -185,9 +217,13 @@ class ConferencesController < ApplicationController
steps -= [:hosting, :questions] steps -= [:hosting, :questions]
end end
if conference.city_id == 433 # if this conference is being held in the "South Pole" (it's a virtual/"Everywhere" event)
steps -= [:hosting, :payment, :questions] # skip hosting b/c there is none & skip payment because we're using OpenCollective
end
return steps return steps
end end
def required_steps(conference = nil) def required_steps(conference = nil)
# return the intersection of current steps and required steps # return the intersection of current steps and required steps
registration_steps(conference || @this_conference || @conference) & # current steps registration_steps(conference || @this_conference || @conference) & # current steps

View File

@ -10,6 +10,8 @@ module ApplicationHelper
include TableHelper include TableHelper
include AdminHelper include AdminHelper
RECAPTCHA_SITE_KEY = ENV['RECAPTCHA_SITE_KEY']
def is_production? def is_production?
Rails.env == 'production' || Rails.env == 'preview' Rails.env == 'production' || Rails.env == 'preview'
end end
@ -21,4 +23,26 @@ module ApplicationHelper
def generate_confirmation(user, url, expiry = nil) def generate_confirmation(user, url, expiry = nil)
ApplicationController::generate_confirmation(user, url, expiry) ApplicationController::generate_confirmation(user, url, expiry)
end end
def include_recaptcha_js
raw %Q{
<script src="https://www.google.com/recaptcha/api.js?render=#{RECAPTCHA_SITE_KEY}"></script>
}
end
def recaptcha_execute(action)
id = "recaptcha_token_#{SecureRandom.hex(10)}"
raw %Q{
<input name="recaptcha_token" type="hidden" id="#{id}"/>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('#{RECAPTCHA_SITE_KEY}', {action: '#{action}'}).then(function(token) {
document.getElementById("#{id}").value = token;
});
});
</script>
}
end
end end

View File

@ -5,8 +5,8 @@ module I18nHelper
url ||= current_path(true) url ||= current_path(true)
return url if Rails.env.development? || Rails.env.test? return url if Rails.env.development? || Rails.env.test?
return "https://preview-#{locale.to_s}.bikebike.org#{url}" if Rails.env.preview? return "https://preview-#{locale.to_s}." + ENV['DEFAULT_URL'] + "#{url}" if Rails.env.preview?
"https://#{locale.to_s}.bikebike.org#{url}" "https://#{locale.to_s}." + ENV['DEFAULT_URL'] + "#{url}"
end end
def current_path(relative = false) def current_path(relative = false)
@ -21,13 +21,13 @@ module I18nHelper
return url_for(new_params) if relative return url_for(new_params) if relative
subdomain = Rails.env.preview? ? "preview-#{locale.to_s}" : locale.to_s subdomain = Rails.env.preview? ? "preview-#{locale.to_s}" : locale.to_s
url_for(new_params.merge(host: "#{subdomain}.bikebike.org")) url_for(new_params.merge(host: "#{subdomain}." + ENV['DEFAULT_URL']))
end end
def canonical_url def canonical_url
url = current_path url = current_path
return url if Rails.env.development? || Rails.env.test? return url if Rails.env.development? || Rails.env.test?
return "https://preview.bikebike.org#{url}" if Rails.env.preview? return ENV['DEFAULT_URL'] + "#{url}" if Rails.env.preview?
"https://bikebike.org#{url}" "https://bikebike.org#{url}"
end end

View File

@ -1,9 +1,14 @@
module RegistrationHelper module RegistrationHelper
def registration_steps(conference = @conference) def registration_steps(conference = @conference)
{ File.write('testingdebug', "in registration_steps (registration_helper\n", mode: 'a')
pre: [:policy, :contact_info, :workshops], if conference.city_name.present? && conference.city_id == 433
open: [:policy, :contact_info, :questions, :hosting, :payment, :workshops] [:policy, :contact_info, :workshops]
}[@this_conference.registration_status] else
{
pre: [:policy, :contact_info, :workshops],
open: [:policy, :contact_info, :questions, :hosting, :payment, :workshops]
}[@this_conference.registration_status]
end
end end
def registration_status(registration) def registration_status(registration)
@ -13,6 +18,7 @@ module RegistrationHelper
end end
def current_registration_steps(registration = @registration) def current_registration_steps(registration = @registration)
File.write('testingdebug', 'in current_registration_steps', mode: 'a')
return nil unless registration.present? return nil unless registration.present?
steps = registration_steps(registration.conference) steps = registration_steps(registration.conference)

View File

@ -6,13 +6,16 @@ class UserMailer < ActionMailer::Base
before_filter :set_host before_filter :set_host
default from: "Bike!Bike! <info@bikebike.org>" default from: "Bike!Bike! <" + ENV['SMTP_USER_NAME'] + ">"
def email_confirmation(confirmation) def email_confirmation(confirmation)
@confirmation = EmailConfirmation.find_by_id(confirmation) if confirmation.present? @confirmation = EmailConfirmation.find_by_id(confirmation) if confirmation.present?
if @confirmation.present? if @confirmation.present?
I18n.locale = @confirmation.user.locale if @confirmation.user.locale.present? I18n.locale = @confirmation.user.locale if @confirmation.user.locale.present?
mail to: @confirmation.user.named_email, subject: clean_subject(_'email.subject.confirm_email','Please confirm your email address') mail to: @confirmation.user.named_email, subject: clean_subject(_'email.subject.confirm_email','Please confirm your email address')
File.write('mailerdebug', @confirmation.user.named_email, mode: 'a')
File.write('mailerdebug', " (in user_mailer.rb at " + Time.now.strftime("%d/%m/%Y %H:%M") + ")\n", mode: 'a')
end end
end end
@ -145,10 +148,14 @@ class UserMailer < ActionMailer::Base
@user = User.find(@request.data['user'].to_i) if @request.data['user'].present? @user = User.find(@request.data['user'].to_i) if @request.data['user'].present?
File.write('mailerdebug', report_signature, mode: 'a')
File.write('mailerdebug', " (in user_mailer.rb at " + Time.now.strftime("%d/%m/%Y %H:%M") + ")\n", mode: 'a')
mail to: administrators, subject: clean_subject(subject), reply_to: @user.present? ? @user.named_email : nil mail to: administrators, subject: clean_subject(subject), reply_to: @user.present? ? @user.named_email : nil
end end
def contact(from, subject, message, email_list) def contact(from, subject, message, email_list)
return if subject =~ /^[a-z]{10}$/
@message = message @message = message
@from = from.is_a?(Integer) ? User.find(from) : from @from = from.is_a?(Integer) ? User.find(from) : from
@ -156,25 +163,26 @@ class UserMailer < ActionMailer::Base
end end
def contact_details(from, subject, message, request, params) def contact_details(from, subject, message, request, params)
return if subject =~ /^[a-z]{10}$/
@message = message @message = message
@from = from.is_a?(Integer) ? User.find(from) : from @from = from.is_a?(Integer) ? User.find(from) : from
@request = request @request = request
@params = params @params = params
mail to: 'goodgodwin@hotmail.com', subject: clean_subject("Details for: \"#{subject}\"") mail to: ENV['ADMIN_EMAIL'], subject: clean_subject("Details for: \"#{subject}\"")
end end
def server_startup(environment) def server_startup(environment)
@environment = environment @environment = environment
mail to: 'goodgodwin@hotmail.com', subject: clean_subject("Deployment to #{environment} complete") mail to: ENV['ADMIN_EMAIL'], subject: clean_subject("Deployment to #{environment} complete")
end end
private private
def set_host(*args) def set_host(*args)
if Rails.env.production? if Rails.env.production?
@host = "https://#{I18n.locale.to_s}.bikebike.org" @host = "https://#{I18n.locale.to_s}." + ENV['DEFAULT_URL']
elsif Rails.env.preview? elsif Rails.env.preview?
@host = "https://preview-#{I18n.locale.to_s}.bikebike.org" @host = "https://preview-#{I18n.locale.to_s}." + ENV['DEFAULT_URL']
else else
@host = UserMailer.default_url_options[:host] @host = UserMailer.default_url_options[:host]
end end

View File

@ -1,6 +1,6 @@
- contact_reason ||= nil -#- contact_reason ||= nil
- locale ||= nil -#- locale ||= nil
= form_tag (locale.present? ? contact_send_url : url_for_locale(locale, contact_send_path)), class: 'contact-form' do -#= form_tag (locale.present? ? contact_send_url : url_for_locale(locale, contact_send_path)), class: 'contact-form' do
= emailfield :email, nil, big: true, required: true unless logged_in? = emailfield :email, nil, big: true, required: true unless logged_in?
- if contact_reason.present? - if contact_reason.present?
= hidden_field_tag :reason, contact_reason = hidden_field_tag :reason, contact_reason

View File

@ -6,4 +6,5 @@
= hidden_field_tag :dest, settings_path if dest.present? = hidden_field_tag :dest, settings_path if dest.present?
= emailfield :email, nil, big: true, required: true = emailfield :email, nil, big: true, required: true
= button :continue, value: :confirm_email = button :continue, value: :confirm_email
= recaptcha_execute('login')
= link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(provider: :facebook, dest: dest), class: [:button, :facebook] = link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(provider: :facebook, dest: dest), class: [:button, :facebook]

View File

@ -6,5 +6,6 @@
%h2=_'articles.contact.headings.sent', :t %h2=_'articles.contact.headings.sent', :t
%p=_'articles.contact.paragraphs.sent', :p %p=_'articles.contact.paragraphs.sent', :p
- else - else
%h2=_'articles.contact.headings.contact' %h2=_'Email info@bikebike.org & bikebikeeverywhere@gmail.com'
= render 'contact', cancel_btn: false -#%h2=_'articles.contact.headings.contact'
-# = render 'contact', cancel_btn: false

View File

@ -6,7 +6,7 @@
.title .title
%h1=_!conference.title %h1=_!conference.title
.details .details
%h2.primary=location(conference.city || conference.location) if conference.city_name.present? %h2.primary=location(conference.city || conference.location) if conference.city_name.present? && conference.city_id != 433
- if conference.start_date.present? && conference.end_date.present? - if conference.start_date.present? && conference.end_date.present?
.secondary .secondary
= date_span(conference.start_date.to_date, conference.end_date.to_date) = date_span(conference.start_date.to_date, conference.end_date.to_date)

View File

@ -8,6 +8,7 @@
= email_field_tag :email, nil, required: true = email_field_tag :email, nil, required: true
= label_tag :email = label_tag :email
= button :continue, value: :confirm_email = button :continue, value: :confirm_email
= recaptcha_execute('conferences_confirm')
= columns(medium: 12, class: 'flex-column') do = columns(medium: 12, class: 'flex-column') do
%p.stretch-item=_'articles.conference_registration.paragraphs.facebook_sign_in' %p.stretch-item=_'articles.conference_registration.paragraphs.facebook_sign_in'
= link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(:provider => :facebook), class: [:button, :facebook] = link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(:provider => :facebook), class: [:button, :facebook]

View File

@ -10,7 +10,7 @@
= stylesheets = stylesheets
%link{ href: asset_path(@favicon), rel: 'shortcut icon', type: 'image/x-icon' } %link{ href: asset_path(@favicon), rel: 'shortcut icon', type: 'image/x-icon' }
%link{ href: asset_path(@favicon), rel: 'icon', type: 'image/x-icon' } %link{ href: asset_path(@favicon), rel: 'icon', type: 'image/x-icon' }
- @alt_lang_urls.each do |locale, url| - (@alt_lang_urls || []).each do |locale, url|
%link{ rel: :alternate, hreflang: locale, href: url } %link{ rel: :alternate, hreflang: locale, href: url }
%link{ href: canonical_url, rel: :canonical } %link{ href: canonical_url, rel: :canonical }
- if content_for?(:og_image) - if content_for?(:og_image)
@ -20,6 +20,7 @@
%meta{property: 'og:type', content: 'website'} %meta{property: 'og:type', content: 'website'}
%meta{property: 'og:image', content: og_image} %meta{property: 'og:image', content: og_image}
%meta{name: "theme-color", content: @theme_colour} %meta{name: "theme-color", content: @theme_colour}
%script{src: "https://www.google.com/recaptcha/api.js?render=#{ENV['RECAPTCHA_SITE_KEY']}" }
= yield :head = yield :head
%body{ class: page_style } %body{ class: page_style }
@ -53,7 +54,7 @@
.dlg-inner .dlg-inner
%p.message='' %p.message=''
%a.button.confirm=_'modals.yes_button' %a.button.confirm=_'modals.yes_button'
%button.delete.close=_'modals.no_button' %button.delete.close=_'modals.no_button'
- if @info_dlg.present? - if @info_dlg.present?
.dlg#info-dlg .dlg#info-dlg
.dlg-content .dlg-content
@ -69,6 +70,8 @@
.message='' .message=''
%button.close=_'modals.done_button' %button.close=_'modals.done_button'
- if @login_dlg.present? - if @login_dlg.present?
= content_for :recaptcha_js do
= include_recaptcha_js
.dlg#login-dlg .dlg#login-dlg
.dlg-content .dlg-content
%h2.title=_'forms.actions.generic.login' %h2.title=_'forms.actions.generic.login'
@ -77,10 +80,11 @@
= hidden_field_tag :dest, settings_path = hidden_field_tag :dest, settings_path
= emailfield :email, nil, big: true = emailfield :email, nil, big: true
= button :continue, value: :confirm_email = button :continue, value: :confirm_email
= recaptcha_execute('sign_in')
.flex-form .flex-form
= link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(provider: :facebook, dest: settings_path), class: [:button, :facebook] = link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(provider: :facebook, dest: settings_path), class: [:button, :facebook]
%button.close.subdued=_'forms.actions.generic.cancel' %button.close.subdued=_'forms.actions.generic.cancel'
- if @event_dlg.present? - if @event_dlg.present?
.event-dlg#event-dlg{ data: { type: :event } } .event-dlg#event-dlg{ data: { type: :event } }
.event-details .event-details

View File

@ -10,17 +10,21 @@
- unless @currencies.present? && @currencies.length > 1 - unless @currencies.present? && @currencies.length > 1
%p.center=_"articles.conference_registration.paragraphs.currency_details", :p, vars: { currency: (_"currencies.#{(@currencies || [@currency]).first}.displayName-count-other") } %p.center=_"articles.conference_registration.paragraphs.currency_details", :p, vars: { currency: (_"currencies.#{(@currencies || [@currency]).first}.displayName-count-other") }
= save_registration_step do = save_registration_step do
.registration-step-options - if @this_conference.slug == "South2022"
.options.graded-options{class: "option-count-#{@amounts.size}"} %iframe{:src => "https://opencollective.com/embed/bikebike-everywhere/donate?email=#{current_user.email}&name=#{current_user.firstname} #{current_user.lastname}", :style => "width: 100%; min-height: 100vh;"}
- @amounts.each_with_index do |option, i| = textfield :notes, @notes, required: true
= button "#{number_to_currency option, unit: '$'} #{_!@currency}".html_safe, value: option, name: :value, class: [:unstyled, "option-#{i + 1}"] - else
.option-space .registration-step-options
.custom-option .options.graded-options{class: "option-count-#{@amounts.size}"}
= number_field_tag :custom_value, 50.0, step: 0.05, min: 0.05 - @amounts.each_with_index do |option, i|
= button :custom_amount, name: :custom_amount, value: :custom, class: :unstyled = button "#{number_to_currency option, unit: '$'} #{_!@currency}".html_safe, value: option, name: :value, class: [:unstyled, "option-#{i + 1}"]
- if @currencies.present? && @currencies.length > 1
.option-space .option-space
.setting-option .custom-option
%p Change currency to: = number_field_tag :custom_value, 50.0, step: 0.05, min: 0.05
- (@currencies - [@currency]).each do |c| = button :custom_amount, name: :custom_amount, value: :custom, class: :unstyled
= button (_"currencies.#{c}.displayName-count-other"), name: :currency, value: c, class: :unstyled - if @currencies.present? && @currencies.length > 1
.option-space
.setting-option
%p Change currency to:
- (@currencies - [@currency]).each do |c|
= button (_"currencies.#{c}.displayName-count-other"), name: :currency, value: c, class: :unstyled

View File

@ -76,7 +76,14 @@
- if guest.housing_data['other'].present? - if guest.housing_data['other'].present?
%td{colspan: 3, lang: guest.user.locale.to_s == I18n.locale.to_s ? nil : guest.user.locale} %td{colspan: 3, lang: guest.user.locale.to_s == I18n.locale.to_s ? nil : guest.user.locale}
= paragraph guest.housing_data['other'] = paragraph guest.housing_data['other']
= row do
= columns(medium: 12) do
- if @this_conference.city_name.present? && @this_conference.city_id == 433
- if @this_conference.payment_message.present?
= richtext @this_conference.payment_message
%iframe{:src => "https://opencollective.com/embed/bikebike-everywhere/donate?amount=30&email=#{current_user.email}&name=#{current_user.firstname} #{current_user.lastname}", :style => "width: 100%; min-height: 100vh;"}
- if @this_conference.registration_open - if @this_conference.registration_open
= row do = row do
= columns(medium: 12) do = columns(medium: 12) do

View File

@ -8,6 +8,7 @@
= email_field_tag :email, nil, required: true = email_field_tag :email, nil, required: true
= label_tag :email = label_tag :email
= button :continue, value: :confirm_email = button :continue, value: :confirm_email
= recaptcha_execute('registration_sign_in')
= columns(medium: 12, class: 'flex-column') do = columns(medium: 12, class: 'flex-column') do
%p.stretch-item=_'articles.conference_registration.paragraphs.facebook_sign_in' %p.stretch-item=_'articles.conference_registration.paragraphs.facebook_sign_in'
= link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(:provider => :facebook), class: [:button, :facebook] = link_to (_'forms.actions.generic.facebook_sign_in','Facebook Sign In'), auth_at_provider_path(:provider => :facebook), class: [:button, :facebook]

View File

@ -17,7 +17,9 @@
= signin_link = signin_link
%ul.locales %ul.locales
.site-info .site-info
.contact-us=link_to (_'links.footer.help_text.contact'), contact_path, id: 'contact-link' -# Commented the line below because the contact form was getting so much spam it was overwhelming the gmail smtp service
-#.contact-us=link_to (_'links.footer.help_text.contact'), contact_path, id: 'contact-link'
.contact-us=link_to 'bikebikeeverywhere@gmail.com', 'mailto:bikebikeeverywhere@gmail.com', id: 'contact-link'
.copy .copy
=_'links.footer.help_text.contributors', 'Who contributed to building this website' do |title| =_'links.footer.help_text.contributors', 'Who contributed to building this website' do |title|
=link_to :humans_txt, {title: title} do =link_to :humans_txt, {title: title} do

View File

@ -23,8 +23,9 @@
= checkboxes :languages, User.AVAILABLE_LANGUAGES, @languages, 'languages', vertical: true, heading: 'articles.workshops.headings.languages', help: 'articles.workshops.paragraphs.languages' = checkboxes :languages, User.AVAILABLE_LANGUAGES, @languages, 'languages', vertical: true, heading: 'articles.workshops.headings.languages', help: 'articles.workshops.paragraphs.languages'
= radiobuttons :theme, Workshop.all_themes, @workshop.theme, 'workshop.options.theme', vertical: true, heading: 'articles.workshops.headings.theme', help: 'articles.workshops.paragraphs.theme', other: true = radiobuttons :theme, Workshop.all_themes, @workshop.theme, 'workshop.options.theme', vertical: true, heading: 'articles.workshops.headings.theme', help: 'articles.workshops.paragraphs.theme', other: true
= columns(medium: 6) do = columns(medium: 6) do
= checkboxes :needs, Workshop.all_needs, JSON.parse(@workshop.needs || '[]'), 'workshop.options.needs', vertical: true, heading: 'articles.workshops.headings.needs', help: 'articles.workshops.paragraphs.needs' - if @this_conference.city_name.present? && @this_conference.city_id != 433
= radiobuttons :space, Workshop.all_spaces, @workshop.space, 'workshop.options.space', vertical: true, heading: 'articles.workshops.headings.space', help: 'articles.workshops.paragraphs.space' = checkboxes :needs, Workshop.all_needs, JSON.parse(@workshop.needs || '[]'), 'workshop.options.needs', vertical: true, heading: 'articles.workshops.headings.needs', help: 'articles.workshops.paragraphs.needs'
= radiobuttons :space, Workshop.all_spaces, @workshop.space, 'workshop.options.space', vertical: true, heading: 'articles.workshops.headings.space', help: 'articles.workshops.paragraphs.space'
%h3#needs_facilitators-label=_'articles.workshops.headings.needs_facilitators','Looking for help?' %h3#needs_facilitators-label=_'articles.workshops.headings.needs_facilitators','Looking for help?'
.input-field-help#needs_facilitators-desc=_'articles.workshops.paragraphs.needs_facilitators', :s, 2 .input-field-help#needs_facilitators-desc=_'articles.workshops.paragraphs.needs_facilitators', :s, 2

BIN
bumbleberry-admin.tar.gz (Stored with Git LFS) Normal file

Binary file not shown.

BIN
bumbleberry-application.tar.gz (Stored with Git LFS) Normal file

Binary file not shown.

BIN
bumbleberry-web-fonts.tar.gz (Stored with Git LFS) Normal file

Binary file not shown.

151
caniuse.js Executable file
View File

@ -0,0 +1,151 @@
#!/usr/bin/node
/* Bumbleberry broke when BikeBike was dockerized, and was updated to more recent and secure Ruby libraries.
This means that it no longer updates properly without breaking BikeBike. In the absense of using Bumbleberry
directly to update the css, when browser version are identified by BikeBike, if they don't exist in /public/stylesheets/*
the browser renders a responsive view, which doesn't look right for normal size screens.
Godwin recommended using the most recent css for the newer versions. This works well for modern browsers.
To enable this feat, the most recent browsers have to be identified, and the css from the most recent version
has to be copied over to the newer version. The irony is we could avoid this exercise, and only support modern browsers
with one css file, but in the spirit of browser justice let's not assume obscure browsers are not being used anymore.
The only disadvantage to this approach would be if a new browser with unknown css arose. Fortunately, this
probably won't be an issue for a long time to come, since new browsers projects almost always adopt the identity of a major
engine: and_chr, and_ff, and_qq, and_uc, android, baidu, bb, chrome, edge, firefox, ie, ie_mob, ios_saf, kaios, op_mini,
op_mobm, opera, safari, samsung
If a new engine does arise, we will deal with that issue when it occurs.
*/
/* retrieves all relevant browers - using default - https://browsersl.ist/
baidu:
{
name: 'baidu',
versions: [ '13.18' ],
released: [ '13.18' ],
releaseDate: { '13.18': 1663027200 }
}
*/
const browserlist = require('browserslist');
const path = require('path');
const fs = require('fs');
const { version } = require('process');
// three directories will be parsed: application, admin, web-fonts
const regex = /.css$/g;
const d = ["admin", "application", "web-fonts"];
d.forEach((dir) => {
caniuse(dir);
});
function caniuse(dir) {
const directory = path.join(__dirname, 'public/stylesheets', dir);
const directoryFiles = {};
fs.readdir(directory, function (err, files) {
//handling error
if (err) {
return console.log('Unable to scan directory: ' + err);
}
//listing all files using forEach
files.forEach((file) => {
if (file.match(regex)) {
//console.log(file)
const browserType = file.split('-', 2)[0];
const bv = file.split('-', 2)[1];
const browserVersion = bv.split('.css', 2)[0];
if (directoryFiles[browserType] === undefined) {
directoryFiles[browserType] = [browserVersion];
} else {
directoryFiles[browserType].push(browserVersion);
}
}
});
// Here's where we process the files according to these rules
// RULES
//
// Find all versions that don't exist for each browser, by comparing to browserlist versions for each browser.
// The most recent css version of the browser will be copied over to each of those newer caniuse versions.
// Fortunately, caniuse versions are sequential in order, so they can be compared easily by beginning at the most recent
// caniuse version, and stepping down to a version that matches an existing version
//
// In some cases, one or more versions of a browser exist, but they don't exist in the browserlist versions.
// This can be tested if a browser file exists with no matching version. In this case, copy the most recent file
// to any new browserlist versions. Example: and_chr, and_ff
//
// If all versions of a browser exists in browerlist, and are exact matches,
// no copying is required. Example: op_mini-all and (bb-7 & bb-10).
// We assume we know all engines that ever existed :)
for (const browser in directoryFiles) {
// This finds the differences between browserlist and the files in the directory
difference = browserlist.data[browser].versions.filter(x => !directoryFiles[browser].includes(x));
// This estables if there are any common items between the two arrays
const commonality = browserlist.data[browser].versions.some(item => directoryFiles[browser].includes(item));
// we only have to copy the most recent css when there is a difference
const browserVersions = browserlist.data[browser].versions;
if (difference.length) {
// console.log(browser + ":")
// console.log("Commonality is", commonality);
// console.log("Directory Files", directoryFiles[browser]);
// console.log("Difference", difference);
// Step down from caniuse versions until there is a match in the directory.
let c = 1;
if (commonality) {
while (browserVersions[browserVersions.length - c]) {
let bV = browserVersions[browserVersions.length - c];
// Use this as the file in the directory to be copied over to the different versions if there is a match.
if (directoryFiles[browser].includes(bV)) {
// console.log("Found", browser + " " + bV);
const recentFile = path.join(directory, browser + "-" + bV + ".css");
// console.log(recentFile)
difference.forEach((ver) => {
let newFile = path.join(__dirname, "public/stylesheets", dir, browser + "-" + ver + ".css");
fs.copyFile(recentFile, newFile, (err) => {
if (err) {
console.log("Error Found:", err);
} else {
// console.log("copied " + recentFile + " to " + newFile);
}
});
});
break;
}
// console.log(browserVersions[browserVersions.length - c]);
c++;
}
}
// If there is no match, use the most recent version in the directory to copy over to the different versions
// It's a safe choice to use the last element as the most recent version
else {
const rV = directoryFiles[browser][directoryFiles[browser].length - 1];
const recentFile = path.join(directory, browser + "-" + rV + ".css");
difference.forEach((ver) => {
let newFile = path.join(__dirname, "public/stylesheets", dir, browser + "-" + ver + ".css");
fs.copyFile(recentFile, newFile, (err) => {
if (err) {
console.log("Error Found:", err);
} else {
// console.log("copied " + recentFile + " to " + newFile);
}
});
});
}
}
}
});
}

22
config/app_config.yml Normal file
View File

@ -0,0 +1,22 @@
default: &default
smtp_address: <%= ENV['SMTP_ADDRESS'] %>
smtp_domain: <%= ENV['SMTP_DOMAIN'] %>
smtp_port: <%= ENV['SMTP_PORT'] %>
smtp_user_name: <%= ENV['SMTP_USER_NAME'] %>
smtp_password: <%= ENV['SMTP_PASSWORD'] %>
smtp_ssl: <%= ENV['SMTP_SSL'] %>
default_url: <%= ENV['DEFAULT_URL'] %>
recaptcha_secret_key: <%= ENV['RECAPTCHA_SECRET_KEY'] %>
recaptcha_site_key: <%= ENV['RECAPTCHA_SITE_KEY'] %>
development:
<<: *default
test:
<<: *default
preview:
<<: *default
production:
<<: *default

View File

@ -1,4 +1,7 @@
BikeBike::Application.configure do BikeBike::Application.configure do
config.app_config = config_for(:app_config)
# Settings specified here will take precedence over those in config/application.rb. # Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded on # In the development environment your application's code is reloaded on
@ -26,19 +29,47 @@ BikeBike::Application.configure do
# This option may cause significant delays in view rendering with a large # This option may cause significant delays in view rendering with a large
# number of complex assets. # number of complex assets.
config.assets.debug = true config.assets.debug = true
config.assets.digest = true config.assets.digest = true
config.assets.compile = true config.assets.compile = true
config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif *.json *.ttf *.otf *.woff *.woff2 *.svg *.json)
# to deliver to the browser instead of email config.assets.unknown_asset_fallback = false
config.action_mailer.delivery_method = :letter_opener config.assets.precompile = ["manifest.js"]
config.action_mailer.raise_delivery_errors = true config.assets.check_precompiled_asset = false
config.action_mailer.perform_deliveries = true
# Version of your assets, change this if you want to expire all your assets.
config.assets.version = '1.01'
config.serve_static_files = true config.serve_static_files = true
I18n.config.language_detection_method = I18n::Config::DETECT_LANGUAGE_FROM_URL_PARAM # to deliver to the browser instead of email
#config.action_mailer.delivery_method = :letter_opener
#config.action_mailer.raise_delivery_errors = true
#config.action_mailer.perform_deliveries = true
Paypal.sandbox! # SMTP real-world test
config.action_controller.default_url_options = { trailing_slash: true } config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: config.app_config['smtp_address'],
domain: config.app_config['smtp_domain'],
port: config.app_config['smtp_port'],
ssl: config.app_config['smtp_ssl'],
authentication: :plain,
enable_starttls_auto: true,
openssl_verify_mode: 'none',
user_name: config.app_config['smtp_user_name'],
password: config.app_config['smtp_password']
}
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_deliveries = true
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found).
config.i18n.fallbacks = true
I18n.config.language_detection_method = I18n::Config::DETECT_LANGUAGE_FROM_SUBDOMAIN
config.action_controller.default_url_options = { host: config.app_config['default_url'], trailing_slash: true }
Sidekiq::Extensions.enable_delay!
#Paypal.sandbox!
#config.action_controller.default_url_options = { trailing_slash: true }
end end

View File

@ -28,7 +28,7 @@ BikeBike::Application.configure do
# config.assets.css_compressor = :sass # config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed. # Do not fallback to assets pipeline if a precompiled asset is missed.
#config.assets.compile = true config.assets.compile = true
# Generate digests for assets URLs. # Generate digests for assets URLs.
config.assets.digest = true config.assets.digest = true
@ -46,8 +46,6 @@ BikeBike::Application.configure do
# Set to :debug to see everything in the log. # Set to :debug to see everything in the log.
config.log_level = :info config.log_level = :info
config.assets.compile = false
# Prepend all log lines with the following tags. # Prepend all log lines with the following tags.
config.log_tags = [ :subdomain, :uuid ] config.log_tags = [ :subdomain, :uuid ]
@ -61,7 +59,8 @@ BikeBike::Application.configure do
# config.action_controller.asset_host = "http://assets.example.com" # config.action_controller.asset_host = "http://assets.example.com"
# Precompile additional assets. # Precompile additional assets.
config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif *.json *.ttf *.otf *.woff *.woff2 *.svg *.json) #config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif *.json *.ttf *.otf *.woff *.woff2 *.svg *.json)
config.assets.precompile = ["manifest.js"]
# Ignore bad email addresses and do not raise email delivery errors. # Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors.
@ -82,18 +81,19 @@ BikeBike::Application.configure do
config.action_mailer.delivery_method = :smtp config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = { config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com', address: config.app_config['smtp_address'],
domain: 'bikebike.org', domain: config.app_config['smtp_domain'],
port: 587, port: config.app_config['smtp_port'],
ssl: config.app_config['smtp_ssl'],
authentication: :plain, authentication: :plain,
enable_starttls_auto: true, enable_starttls_auto: true,
openssl_verify_mode: 'none', openssl_verify_mode: 'none',
user_name: 'info@bikebike.org', user_name: config.app_config['smtp_user_name'],
password: config.app_config['email_password'] password: config.app_config['smtp_password']
} }
config.action_mailer.raise_delivery_errors = true config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_deliveries = true config.action_mailer.perform_deliveries = true
I18n.config.language_detection_method = I18n::Config::DETECT_LANGUAGE_FROM_SUBDOMAIN I18n.config.language_detection_method = I18n::Config::DETECT_LANGUAGE_FROM_SUBDOMAIN
config.action_controller.default_url_options = { host: 'https://bikebike.org', trailing_slash: true } config.action_controller.default_url_options = { host: config.app_config['default_url'], trailing_slash: true }
Sidekiq::Extensions.enable_delay! Sidekiq::Extensions.enable_delay!
end end

View File

@ -4,7 +4,17 @@
Twitter: @__Godwin__ Twitter: @__Godwin__
From:Seattle, Washington, USA From:Seattle, Washington, USA
Other Developers:See our Github Senior System Administrator, Developer and Dockerizer: Jonathan Rosenbaum
Contact: bike [at] bikelover.org
From:Morgantown, West Virginia, USA
Tech Tinkerer and Developer: April Wick
Contact: darin [at] darinwick.com
Current Developers: See our new Git with lfs
Website: https://git.bikeshopi.dev/bike/BikeBikeBike/
Other Historic Developers:See our Github
Website: https://github.com/bikebike/BikeBike Website: https://github.com/bikebike/BikeBike
Primary ES Translators:Jim Mayerstein; Ollin Monroy Primary ES Translators:Jim Mayerstein; Ollin Monroy
@ -19,7 +29,7 @@
Thanks to everyone else who contributed translations, code, copy, photography, and general support! Thanks to everyone else who contributed translations, code, copy, photography, and general support!
/* SITE */ /* SITE */
Last update:2015/09/15 Last update:2023/07/18
Language: English Language: English
Doctype:HTML5 Doctype:HTML5
IDE: Sublime Text, Photoshop IDE: Visual Studio Code, Sublime Text, Photoshop

View File

@ -1797,7 +1797,7 @@ en:
payment_form: Registration Fee Amount payment_form: Registration Fee Amount
org_select: Which organization are you a member of? org_select: Which organization are you a member of?
payment_type: Registration Fee Method payment_type: Registration Fee Method
housing_other: Other considerations housing_other: Information for organizers
housing_allergies: Do you have any allergies? housing_allergies: Do you have any allergies?
housing_food: What are your eating habits? housing_food: What are your eating habits?
housing_bike: Would you like to borrow a bike? housing_bike: Would you like to borrow a bike?
@ -1946,16 +1946,16 @@ en:
to populate the list of known organizations that will be displayed on bikecollectives.org. to populate the list of known organizations that will be displayed on bikecollectives.org.
If you are involved with multiple organizations, please select one for now, If you are involved with multiple organizations, please select one for now,
you will be able to add more organizations at a later date. you will be able to add more organizations at a later date.
payment_type: If you can, please pay now via PayPal. We collect the registration payment_type: If you can, please pay now online. We collect the registration
fee as a donation. Your donation pays for spaces, food, equipment, and much fee as a donation. Your donation pays for spaces, food, equipment, and much
more. Paying now enables us to prepare for the conference without paying more. Paying now enables us to prepare for the conference without paying
out of our own pockets. Otherwise, please pledge to pay on arrival. Your out of our own pockets. Otherwise, please pledge to pay on arrival. Your
pledge will help us make a rough plan for what we can and cannot afford. pledge will help us make a rough plan for what we can and cannot afford.
Thank you. Thank you.
housing_other: Do you have any special needs or considerations that we should housing_other: Please enter any information you would like organizers to consider
know about for your stay such as allergies, disabilities, or a need for when preparing for your visit. If you have restrictions in terms of mobility,
child care? Letting us know in advance will help us determine the best place diet or allergies, or preferences on the accommodations or guests that we will
for you to stay and make any necessary preparations for the conference itself. place you with, please list them here.
housing_allergies: Let us know if you have any allergies that we should be housing_allergies: Let us know if you have any allergies that we should be
made aware of. made aware of.
housing_food: Please let us know your eating habits by selecting the option housing_food: Please let us know your eating habits by selecting the option
@ -1972,11 +1972,13 @@ en:
housing_departure_date: When will you be leaving %{city}? If you wish to stay housing_departure_date: When will you be leaving %{city}? If you wish to stay
in town longer and need housing or a bike after %{max_date}, please select in town longer and need housing or a bike after %{max_date}, please select
this date on the calendar below and contact us after you complete your registration. this date on the calendar below and contact us after you complete your registration.
We cannot guarantee that we can accommodate you but we will do our best. We cannot guarantee that we can accommodate you but we will do our best.
(For virtual conferences select the last day you are available.)
housing_arrival_date: When will you be arriving in %{city}? If you will be housing_arrival_date: When will you be arriving in %{city}? If you will be
in town and need housing or a bike before %{min_date}, please select this in town and need housing or a bike before %{min_date}, please select this
date on the calendar below and contact us after you complete your registration. date on the calendar below and contact us after you complete your registration.
We cannot guarantee that we can accommodate you but we will do our best. We cannot guarantee that we can accommodate you but we will do our best.
(For virtual conferences select the first day you are available.)
org_create_mailing_address: Please provide the organization's mailing address org_create_mailing_address: Please provide the organization's mailing address
so that we can send your organization a personal invite and poster for next so that we can send your organization a personal invite and poster for next
year's Bike!Bike!. year's Bike!Bike!.
@ -2438,7 +2440,7 @@ en:
reopen_registration: Re-open my registration reopen_registration: Re-open my registration
cancel_registration: Cancel my registration cancel_registration: Cancel my registration
organization_none: None of the above organization_none: None of the above
payment_paypal: I can pay now with PayPal payment_paypal: I can pay now online
payment_on_arrival: I can pledge to pay on arrival payment_on_arrival: I can pledge to pay on arrival
payment_none: Not now payment_none: Not now
food_meat: I eat meat and dairy food_meat: I eat meat and dairy
@ -2454,7 +2456,7 @@ en:
back: Back back: Back
upload: Upload upload: Upload
select_file: Select a file select_file: Select a file
administrate: Administrate administrate: Administer
login: Sign In login: Sign In
Log_out: Sign out Log_out: Sign out
agree: I Agree agree: I Agree

View File

@ -1346,7 +1346,7 @@ es:
can_provide_housing: "¿Puedes proporcionar hospedaje a quienes visitan la can_provide_housing: "¿Puedes proporcionar hospedaje a quienes visitan la
ciudad?" ciudad?"
Verify_Account: Verifica tu cuenta Verify_Account: Verifica tu cuenta
policy: Normatividad policy: Normas
Contact_Info: Información de contacto Contact_Info: Información de contacto
contact_info: Información de contacto contact_info: Información de contacto
Administration: Administrar cuenta Administration: Administrar cuenta
@ -1384,7 +1384,7 @@ es:
housing_companion_email: Correo electrónico de tu acompañante housing_companion_email: Correo electrónico de tu acompañante
housing_departure_date: Fecha de partida housing_departure_date: Fecha de partida
housing_food: Cuáles son tus hábitos alimenticios? housing_food: Cuáles son tus hábitos alimenticios?
housing_other: Otras consideraciones housing_other: Información para organizadores
housing_type: Hospedaje housing_type: Hospedaje
org_create_address: Dirección de tu organización org_create_address: Dirección de tu organización
org_create_email: Correo electrónico de tu organización org_create_email: Correo electrónico de tu organización
@ -1550,7 +1550,8 @@ es:
housing_arrival_date: Cuándo llegarás a %{city}? Si vas a llegar a la ciudad housing_arrival_date: Cuándo llegarás a %{city}? Si vas a llegar a la ciudad
antes de %{min_date} y necesitas hospedaje o una bici, por favor selecciona antes de %{min_date} y necesitas hospedaje o una bici, por favor selecciona
la fecha en el calendario que está abajo y contáctanos después de que termines la fecha en el calendario que está abajo y contáctanos después de que termines
tu registro. No podemos garantizarte hospedaje, pero haremos lo posible. tu registro. No podemos garantizarte hospedaje, pero haremos lo posible.
(Para conferencias virtuales seleccione el primer día que esté disponible.)
housing_bike: Para hacernos una idea de cuántas bicicletas necesitamos preparar, housing_bike: Para hacernos una idea de cuántas bicicletas necesitamos preparar,
por favor avísanos si te gustaría que te prestáramos una bicicleta. por favor avísanos si te gustaría que te prestáramos una bicicleta.
housing_companion_check: Viajas con tu pareja o con alguien que definitivamente housing_companion_check: Viajas con tu pareja o con alguien que definitivamente
@ -1562,17 +1563,16 @@ es:
tiempo y necesitas hospedaje o una bici después de %{max_date}, por favor tiempo y necesitas hospedaje o una bici después de %{max_date}, por favor
selecciona las fechas en el calendario de bajo y contáctanos después de selecciona las fechas en el calendario de bajo y contáctanos después de
concluir tu registro. No podemos garantizarte hospedaje pero haremos lo concluir tu registro. No podemos garantizarte hospedaje pero haremos lo
posible. posible.
(Para conferencias virtuales seleccione el ultimo día que esté disponible.)
housing_food: Por favor cuéntanos de tus hábitos alimenticios seleccionando housing_food: Por favor cuéntanos de tus hábitos alimenticios seleccionando
la opción que mejor describa el tipo de comida que comes. Usaremos esto la opción que mejor describa el tipo de comida que comes. Usaremos esto
para decidir el tipo de comidas que prepararemos y la cantidad de alimentos para decidir el tipo de comidas que prepararemos y la cantidad de alimentos
que necesitaremos. que necesitaremos.
housing_other: Tienes algún requerimiento especial o consideraciones que creas housing_other: Ingrese cualquier información que le gustaría que los organizadores
que debamos tener respecto a tu estadía, tales como alergias, limitaciones consideren para su visita. Si tiene restricciones de movilidad, dieta o alergias,
de movilidad o discapacidades, o si necesitas guardería? Hacérnoslo saber o preferencias de alojamiento (ej. preferencia de huéspedes para compartir
por adelantado nos ayudará a determinar mejor el lugar en el que te hospedarás alojamiento), indíquelos aquí por favor.
y si es necesario, preparar los mismos lugares en los que se realizará la
conferencia para tu mejor accesibilidad a ellos.
housing_type: Necesitas un lugar para quedarte en %{city} ? Haremos lo posible housing_type: Necesitas un lugar para quedarte en %{city} ? Haremos lo posible
por ubicarte con un(a) anfitrión(a) local y con lxs visitantes que mejor por ubicarte con un(a) anfitrión(a) local y con lxs visitantes que mejor
coincidan con tus necesidades.  coincidan con tus necesidades. 
@ -1735,7 +1735,7 @@ es:
org_select: Organización org_select: Organización
payment_form: Cantidad a pagar por registro payment_form: Cantidad a pagar por registro
payment_type: Método de pago para el registro payment_type: Método de pago para el registro
policy: Normatividad policy: Normas
housing_bike: Necesitas bici? housing_bike: Necesitas bici?
warning: warning:
companion_unregistered: Tu acompañante no se ha registrado. Por favor aseguráte companion_unregistered: Tu acompañante no se ha registrado. Por favor aseguráte
@ -2061,7 +2061,7 @@ es:
Locale_Not_Available: Locale no disponible Locale_Not_Available: Locale no disponible
'500': '500':
An_Error_Occurred: Ocurrió un error An_Error_Occurred: Ocurrió un error
Policy: Normatividad Policy: Normas
About: Acerca de About: Acerca de
Register: Regístrate Register: Regístrate
Pre_Register: Pre-Regístrate Pre_Register: Pre-Regístrate

View File

@ -1212,7 +1212,7 @@ fr:
hosting_space_tent: Hébergement sous tente hosting_space_tent: Hébergement sous tente
hosting_start_date: Date de début de lhébergement hosting_start_date: Date de début de lhébergement
housing_bike: Souhaitez-vous emprunter un vélo? housing_bike: Souhaitez-vous emprunter un vélo?
housing_other: Autres précisions housing_other: Informations pour les organisateurs
housing_type: Hébergement housing_type: Hébergement
hosting_end_date: Date de fin de lhébergement hosting_end_date: Date de fin de lhébergement
housing_companion_check: Hébergement pour deux personnes housing_companion_check: Hébergement pour deux personnes
@ -1376,20 +1376,23 @@ fr:
et que vous avez besoin dun hébergement ou dun vélo avant %{min_date}, et que vous avez besoin dun hébergement ou dun vélo avant %{min_date},
veuillez sélectionnez vos dates dans le calendrier ci-dessous et nous contacter veuillez sélectionnez vos dates dans le calendrier ci-dessous et nous contacter
afin de compléter votre inscription. Nous ne pouvons garantir que nous pourrons afin de compléter votre inscription. Nous ne pouvons garantir que nous pourrons
vous accommoder, mais nous ferons de notre mieux. vous accommoder, mais nous ferons de notre mieux.
(Pour les conférences virtuelles, sélectionnez le premier jour où vous êtes disponible.)
housing_departure_date: Quand allez-vous quitter %{city}? Si vous voulez rester housing_departure_date: Quand allez-vous quitter %{city}? Si vous voulez rester
plus longtemps et que vous avez besoin d'un hébergement et d'un vélo après plus longtemps et que vous avez besoin d'un hébergement et d'un vélo après
%{max_date}, veuillez sélectionner cette date dans le calendrier ci-dessous %{max_date}, veuillez sélectionner cette date dans le calendrier ci-dessous
et nous joindre une fois que vous avez fini de vous inscrire. Nous ne pouvons et nous joindre une fois que vous avez fini de vous inscrire. Nous ne pouvons
vous promettre un hébergement, mais nous ferons notre possible pour vous vous promettre un hébergement, mais nous ferons notre possible pour vous
aider. aider.
(Pour les conférences virtuelles, sélectionnez le dernier jour où vous êtes disponible.)
housing_food: Veuillez nous renseigner sur vos habitudes alimentaires en choisissant housing_food: Veuillez nous renseigner sur vos habitudes alimentaires en choisissant
l'option qui vous correspond le mieux. Cela nous aidera à préparer de meilleurs l'option qui vous correspond le mieux. Cela nous aidera à préparer de meilleurs
repas et à prévoir des quantités de nourriture adaptées. repas et à prévoir des quantités de nourriture adaptées.
housing_other: Avez-vous des besoins spéciaux ou d'autres besoins à prendre housing_other: "Merci d'indiquer toutes les informations que vous désirez porter à
en compte, tel que des allergies, des incapacités ou du gardiennage d'enfants? l'attention des organisateurs, afin qu'elles puissent être prises en compte dans
Veuillez le préciser ici afin de nous aider à vous trouver un hébergement l'organisation de votre séjour. Si vous avez des besoins en matière d'accessibilité,
adapté et à organiser le congrès. un régime particulier ou des allergies, ou si vous avez des préférences concernant
votre hébergement et votre hôte : listez tout celà ici."
housing_type: Avez-vous besoin d'un hébergement à %{city}? Nous ferons notre housing_type: Avez-vous besoin d'un hébergement à %{city}? Nous ferons notre
possible pour trouver des hébergements adaptés aux besoins de tous et de possible pour trouver des hébergements adaptés aux besoins de tous et de
toutes. toutes.

View File

@ -1,3 +1,6 @@
require 'sidekiq/web'
Sidekiq::Web.set :sessions, false
BikeBike::Application.routes.draw do BikeBike::Application.routes.draw do
# Conferences # Conferences
@ -7,7 +10,7 @@ BikeBike::Application.routes.draw do
get 'new' => 'administration#new', as: :new_conference get 'new' => 'administration#new', as: :new_conference
post 'save' => 'administration#save', as: :save_conference post 'save' => 'administration#save', as: :save_conference
scope ':slug' do scope ':slug', constraints: { slug: /[^\/]+/ } do
root 'conferences#view', as: :conference root 'conferences#view', as: :conference
get 'edit' => 'administration#edit', as: :edit_conference get 'edit' => 'administration#edit', as: :edit_conference
@ -71,12 +74,12 @@ BikeBike::Application.routes.draw do
end end
# Contact # Contact
scope :contact do # scope :contact do
root 'application#contact', as: :contact # root 'application#contact', as: :contact
post 'send' => 'application#contact_send', as: :contact_send # post 'send' => 'application#contact_send', as: :contact_send
get 'sent' => 'application#contact_sent', as: :contact_sent # get 'sent' => 'application#contact_sent', as: :contact_sent
end # end
# Static pages # Static pages
get 'about' => 'application#about', as: :about get 'about' => 'application#about', as: :about
@ -96,4 +99,7 @@ BikeBike::Application.routes.draw do
# Home page # Home page
root 'application#home', as: :home root 'application#home', as: :home
# Sidkiq Web UI
mount Sidekiq::Web => "/sidekiq"
end end

View File

@ -27,9 +27,9 @@ ActiveRecord::Schema.define(version: 20170817000540) do
end end
create_table "authentications", force: :cascade do |t| create_table "authentications", force: :cascade do |t|
t.integer "user_id", null: false t.integer "user_id", null: false
t.string "provider", null: false t.string "provider", limit: 255, null: false
t.string "uid", null: false t.string "uid", limit: 255, null: false
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end
@ -103,18 +103,18 @@ ActiveRecord::Schema.define(version: 20170817000540) do
create_table "conference_registrations", force: :cascade do |t| create_table "conference_registrations", force: :cascade do |t|
t.integer "conference_id" t.integer "conference_id"
t.integer "user_id" t.integer "user_id"
t.string "is_attending" t.string "is_attending", limit: 255
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.boolean "is_confirmed" t.boolean "is_confirmed"
t.boolean "is_participant" t.boolean "is_participant"
t.boolean "is_volunteer" t.boolean "is_volunteer"
t.string "confirmation_token" t.string "confirmation_token", limit: 255
t.string "email" t.string "email", limit: 255
t.boolean "complete" t.boolean "complete"
t.boolean "completed" t.boolean "completed"
t.string "payment_confirmation_token" t.string "payment_confirmation_token", limit: 255
t.string "payment_info" t.string "payment_info", limit: 255
t.integer "registration_fees_paid" t.integer "registration_fees_paid"
t.string "city" t.string "city"
t.datetime "arrival" t.datetime "arrival"
@ -135,21 +135,21 @@ ActiveRecord::Schema.define(version: 20170817000540) do
end end
create_table "conference_types", force: :cascade do |t| create_table "conference_types", force: :cascade do |t|
t.string "title" t.string "title", limit: 255
t.string "info" t.string "info", limit: 255
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "slug" t.string "slug", limit: 255
end end
create_table "conferences", force: :cascade do |t| create_table "conferences", force: :cascade do |t|
t.string "title" t.string "title", limit: 255
t.string "slug" t.string "slug", limit: 255
t.date "start_date" t.date "start_date"
t.date "end_date" t.date "end_date"
t.text "info" t.text "info"
t.string "poster" t.string "poster", limit: 255
t.string "cover" t.string "cover", limit: 255
t.boolean "workshop_schedule_published" t.boolean "workshop_schedule_published"
t.boolean "registration_open" t.boolean "registration_open"
t.boolean "meals_provided" t.boolean "meals_provided"
@ -162,8 +162,8 @@ ActiveRecord::Schema.define(version: 20170817000540) do
t.text "registration_info" t.text "registration_info"
t.text "postregistration_info" t.text "postregistration_info"
t.integer "cover_attribution_id" t.integer "cover_attribution_id"
t.string "cover_attribution_name" t.string "cover_attribution_name", limit: 255
t.string "cover_attribution_src" t.string "cover_attribution_src", limit: 255
t.integer "cover_attribution_user_id" t.integer "cover_attribution_user_id"
t.string "locale" t.string "locale"
t.string "email_address" t.string "email_address"
@ -241,15 +241,15 @@ ActiveRecord::Schema.define(version: 20170817000540) do
end end
create_table "event_types", force: :cascade do |t| create_table "event_types", force: :cascade do |t|
t.string "slug" t.string "slug", limit: 255
t.text "info" t.text "info"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end
create_table "events", force: :cascade do |t| create_table "events", force: :cascade do |t|
t.string "title" t.string "title", limit: 255
t.string "slug" t.string "slug", limit: 255
t.integer "event_type_id" t.integer "event_type_id"
t.integer "conference_id" t.integer "conference_id"
t.text "info" t.text "info"
@ -272,16 +272,16 @@ ActiveRecord::Schema.define(version: 20170817000540) do
end end
create_table "locations", force: :cascade do |t| create_table "locations", force: :cascade do |t|
t.string "title" t.string "title", limit: 255
t.float "latitude" t.float "latitude"
t.float "longitude" t.float "longitude"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "country" t.string "country", limit: 255
t.string "territory" t.string "territory", limit: 255
t.string "city" t.string "city", limit: 255
t.string "street" t.string "street", limit: 255
t.string "postal_code" t.string "postal_code", limit: 255
t.integer "city_id" t.integer "city_id"
end end
@ -295,33 +295,33 @@ ActiveRecord::Schema.define(version: 20170817000540) do
add_index "locations_organizations", ["organization_id", "location_id"], name: "loc_org_index", using: :btree add_index "locations_organizations", ["organization_id", "location_id"], name: "loc_org_index", using: :btree
create_table "organization_statuses", force: :cascade do |t| create_table "organization_statuses", force: :cascade do |t|
t.string "name" t.string "name", limit: 255
t.string "slug" t.string "slug", limit: 255
t.string "info" t.string "info", limit: 255
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end
create_table "organizations", force: :cascade do |t| create_table "organizations", force: :cascade do |t|
t.string "name" t.string "name", limit: 255
t.string "slug" t.string "slug", limit: 255
t.string "email_address" t.string "email_address", limit: 255
t.string "url" t.string "url", limit: 255
t.integer "year_founded" t.integer "year_founded"
t.text "info" t.text "info"
t.string "logo" t.string "logo", limit: 255
t.string "avatar" t.string "avatar", limit: 255
t.boolean "requires_approval" t.boolean "requires_approval"
t.string "secret_question" t.string "secret_question", limit: 255
t.string "secret_answer" t.string "secret_answer", limit: 255
t.integer "user_organization_replationship_id" t.integer "user_organization_replationship_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "cover" t.string "cover", limit: 255
t.integer "cover_attribution_id" t.integer "cover_attribution_id"
t.string "cover_attribution_name" t.string "cover_attribution_name", limit: 255
t.string "cover_attribution_src" t.string "cover_attribution_src", limit: 255
t.string "phone" t.string "phone", limit: 255
t.integer "organization_status_id" t.integer "organization_status_id"
t.integer "cover_attribution_user_id" t.integer "cover_attribution_user_id"
t.string "status" t.string "status"
@ -352,11 +352,11 @@ ActiveRecord::Schema.define(version: 20170817000540) do
end end
create_table "registration_form_fields", force: :cascade do |t| create_table "registration_form_fields", force: :cascade do |t|
t.string "title" t.string "title", limit: 255
t.text "help" t.text "help"
t.boolean "required" t.boolean "required"
t.string "field_type" t.string "field_type", limit: 255
t.string "options" t.string "options", limit: 255
t.boolean "is_retired" t.boolean "is_retired"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
@ -383,7 +383,7 @@ ActiveRecord::Schema.define(version: 20170817000540) do
end end
create_table "sessions", force: :cascade do |t| create_table "sessions", force: :cascade do |t|
t.string "session_id", null: false t.string "session_id", limit: 255, null: false
t.text "data" t.text "data"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
@ -417,11 +417,11 @@ ActiveRecord::Schema.define(version: 20170817000540) do
end end
create_table "translations", force: :cascade do |t| create_table "translations", force: :cascade do |t|
t.string "locale" t.string "locale", limit: 255
t.string "key" t.string "key", limit: 255
t.text "value" t.text "value"
t.text "interpolations" t.text "interpolations"
t.boolean "is_proc", default: false t.boolean "is_proc", default: false
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end
@ -429,34 +429,34 @@ ActiveRecord::Schema.define(version: 20170817000540) do
create_table "user_organization_relationships", force: :cascade do |t| create_table "user_organization_relationships", force: :cascade do |t|
t.integer "user_id" t.integer "user_id"
t.integer "organization_id" t.integer "organization_id"
t.string "relationship" t.string "relationship", limit: 255
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end
create_table "users", force: :cascade do |t| create_table "users", force: :cascade do |t|
t.string "username" t.string "username"
t.string "email" t.string "email", limit: 255
t.string "crypted_password" t.string "crypted_password", limit: 255
t.string "salt" t.string "salt", limit: 255
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "remember_me_token" t.string "remember_me_token", limit: 255
t.datetime "remember_me_token_expires_at" t.datetime "remember_me_token_expires_at"
t.string "reset_password_token" t.string "reset_password_token", limit: 255
t.datetime "reset_password_token_expires_at" t.datetime "reset_password_token_expires_at"
t.datetime "reset_password_email_sent_at" t.datetime "reset_password_email_sent_at"
t.string "activation_state" t.string "activation_state", limit: 255
t.string "activation_token" t.string "activation_token", limit: 255
t.datetime "activation_token_expires_at" t.datetime "activation_token_expires_at"
t.integer "failed_logins_count", default: 0 t.integer "failed_logins_count", default: 0
t.datetime "lock_expires_at" t.datetime "lock_expires_at"
t.string "unlock_token" t.string "unlock_token", limit: 255
t.string "avatar" t.string "avatar", limit: 255
t.text "about_me" t.text "about_me"
t.string "role" t.string "role", limit: 255
t.string "firstname" t.string "firstname", limit: 255
t.string "lastname" t.string "lastname", limit: 255
t.boolean "is_translator" t.boolean "is_translator"
t.json "languages" t.json "languages"
t.string "locale" t.string "locale"
@ -473,19 +473,19 @@ ActiveRecord::Schema.define(version: 20170817000540) do
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", using: :btree add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", using: :btree
create_table "versions", force: :cascade do |t| create_table "versions", force: :cascade do |t|
t.string "item_type" t.string "item_type", limit: 255
t.integer "item_id" t.integer "item_id"
t.string "event" t.string "event", limit: 255
t.string "whodunnit" t.string "whodunnit", limit: 255
t.text "object" t.text "object"
t.datetime "created_at" t.datetime "created_at"
t.string "value" t.string "value", limit: 255
end end
create_table "workshop_facilitators", force: :cascade do |t| create_table "workshop_facilitators", force: :cascade do |t|
t.integer "user_id" t.integer "user_id"
t.integer "workshop_id" t.integer "workshop_id"
t.string "role" t.string "role", limit: 255
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end
@ -498,9 +498,9 @@ ActiveRecord::Schema.define(version: 20170817000540) do
end end
create_table "workshop_presentation_styles", force: :cascade do |t| create_table "workshop_presentation_styles", force: :cascade do |t|
t.string "name" t.string "name", limit: 255
t.string "slug" t.string "slug", limit: 255
t.string "info" t.string "info", limit: 255
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.integer "order" t.integer "order"
@ -509,31 +509,31 @@ ActiveRecord::Schema.define(version: 20170817000540) do
create_table "workshop_requested_resources", force: :cascade do |t| create_table "workshop_requested_resources", force: :cascade do |t|
t.integer "workshop_id" t.integer "workshop_id"
t.integer "workshop_resource_id" t.integer "workshop_resource_id"
t.string "status" t.string "status", limit: 255
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end
create_table "workshop_resources", force: :cascade do |t| create_table "workshop_resources", force: :cascade do |t|
t.string "name" t.string "name", limit: 255
t.string "slug" t.string "slug", limit: 255
t.string "info" t.string "info", limit: 255
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end
create_table "workshop_streams", force: :cascade do |t| create_table "workshop_streams", force: :cascade do |t|
t.string "name" t.string "name", limit: 255
t.string "slug" t.string "slug", limit: 255
t.string "info" t.string "info", limit: 255
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.integer "order" t.integer "order"
end end
create_table "workshops", force: :cascade do |t| create_table "workshops", force: :cascade do |t|
t.string "title" t.string "title", limit: 255
t.string "slug" t.string "slug", limit: 255
t.text "info" t.text "info"
t.integer "conference_id" t.integer "conference_id"
t.integer "workshop_stream_id" t.integer "workshop_stream_id"

12
docker-compose.build Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
# This assume docker compose build, which takes a long time and builds the image, has already happened,
# it should on up -d.
# Also, you may need to remove and create the external volumes again for the steps
# below to work correctly.
docker compose up -d
docker compose run --rm bikebike rake db:setup
docker compose run --rm bikebike rake db:migrate
docker compose run --rm bikebike rake assets:precompile
docker compose down
docker compose up -d

149
docker-compose.yml Normal file
View File

@ -0,0 +1,149 @@
# BikeBike
#
# ENV DATABASE_URL string = https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING
#
# docker-compose.build:
#
# docker compose up -d
# docker compose run --rm bikebike rake db:setup
# docker compose run --rm bikebike rake db:migrate
# docker compose run --rm bikebike rake assets:precompile
# docker compose down
# docker compose up -d
#
# Never do this because new sprockets and manifest.js isn't precompiling to *css, and breaks the container
# -- docker-compose run bikebike rake bumbleberry:update --
#
# This is why we resort to git lfs, and utilize precompiled css,
# which is updated as requuired to newest modern browsers with caniuse.js
#
# exporting database: pg_dump -c -U bike_bike bike_bike > bike_bike.sql
services:
redis:
# container_name: bikebikebike-redis
image: redis:6.2-alpine
ports:
- "6379"
restart: always
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
#volumes:
# -
# Run sidekiq as it's own process using the same image that bikbike uses!
sidekiq:
image: bikebikebike
# container_name: bikebikebike-sidekiq
command: sidekiq -q production
environment:
- REDIS_URL=redis://redis:6379
- DATABASE_URL=${DATABASE_URL:-postgresql://bike_bike:password@db/bike_bike?encoding=unicode&pool=5}
- PORT=3000
- RAILS_ENV=${RAILS_ENV:-production}
- SMTP_ADDRESS=${SMTP_ADDRESS:-fake-smtp.bikebike.org}
- SMTP_DOMAIN=${SMTP_DOMAIN:-bikebike.org}
- SMTP_PORT=${SMTP_PORT:-587}
- SMTP_USER_NAME=${SMTP_USER_NAME:-info@bikebike.org}
- SMTP_PASSWORD=${SMTP_PASSWORD:-fake}
- SMTP_SSL=${SMTP_SSL:-false}
- ADMIN_EMAIL=${ADMIN_EMAIL:-info@bikebike.org}
- DEFAULT_URL=${DEFAULT_URL:-bikebike.org}
restart: always
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
db:
# container_name: bikebikebike-db
image: postgres:9.5
ports:
- "5432"
restart: always
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
- bikebikebike_db:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_USER=bike_bike
- POSTGRES_DB=bike_bike
bikebike:
build: .
image: bikebikebike
# container_name: bikebikebike
networks:
letsencrypt:
default:
command: /bin/sh -c "rm -f /app/BikeBike/tmp/pids/server.pid && rails server -b '0.0.0.0'"
# Add environment values that are not in .env (environment:) below in the bike_bike_advanced_environment file
# Empty file ok, too, or just comment out this section
env_file:
- bike_bike_advanced_environment
# Add your own environment values in .env, or use the default ones
environment:
- PORT=3000
- RAILS_ENV=${RAILS_ENV:-production}
- DATABASE_URL=${DATABASE_URL:-postgresql://bike_bike:password@db/bike_bike?encoding=unicode&pool=5}
- SMTP_ADDRESS=${SMTP_ADDRESS:-fake-smtp.bikebike.org}
- SMTP_DOMAIN=${SMTP_DOMAIN:-bikebike.org}
- SMTP_PORT=${SMTP_PORT:-587}
- SMTP_USER_NAME=${SMTP_USER_NAME:-info@bikebike.org}
- SMTP_PASSWORD=${SMTP_PASSWORD:-fake}
- SMTP_SSL=${SMTP_SSL:-false}
- ADMIN_EMAIL=${ADMIN_EMAIL:-info@bikebike.org}
- DEFAULT_URL=${DEFAULT_URL:-bikebike.org}
- REDIS_URL=redis://redis:6379
- RECAPTCHA_SECRET_KEY=${RECAPTCHA_SECRET_KEY:-123456789}
- RECAPTCHA_SITE_KEY=${RECAPTCHA_SITE_KEY:-123456789}
volumes:
- bikebikebike:/app/BikeBike
- bikebikebike_bundle:/usr/local/bundle
- bikebikebike_uploads:/app/BikeBike/public/uploads
expose:
- "3000"
links:
- db
# Make sure to rename container to what is being used
labels:
ofelia.enabled: "true" # in rss2email
ofelia.job-exec.bikebikebike-caniuse.schedule: "@every 6h"
ofelia.job-exec.bikebikebike-caniuse.container: "bikebikebike"
ofelia.job-exec.bikebikebike-caniuse.command: "/app/BikeBike/caniuse.js"
ofelia.job-exec.bikebikebike-caniuse.user: "root:root"
ofelia.job-exec.bikebikebike-browserlist.schedule: "@every 24h"
ofelia.job-exec.bikebikebike-browserlist.container: "bikebikebike"
ofelia.job-exec.bikebikebike-browserlist.command: "/root/.local/share/pnpm/pnpm update browserlist@latest"
ofelia.job-exec.bikebikebike-browserlist.user: "root:root"
restart: always
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# Currently set to false for all volumes for development
volumes:
bikebikebike_db:
external: false
bikebikebike:
external: false
bikebikebike_bundle:
external: false
bikebikebike_uploads:
external: false
# Remove this network if you don't use it
networks:
letsencrypt:
external: true

8
entrypoint.sh Normal file
View File

@ -0,0 +1,8 @@
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/BikeBike/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

6
package.json Normal file
View File

@ -0,0 +1,6 @@
{
"dependencies": {
"browserslist": "^4.22.2",
"npx": "^10.2.2"
}
}

66
pnpm-lock.yaml generated Normal file
View File

@ -0,0 +1,66 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies:
browserslist:
specifier: ^4.22.2
version: 4.22.2
npx:
specifier: ^10.2.2
version: 10.2.2
packages:
/browserslist@4.22.2:
resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
caniuse-lite: 1.0.30001576
electron-to-chromium: 1.4.631
node-releases: 2.0.14
update-browserslist-db: 1.0.13(browserslist@4.22.2)
dev: false
/caniuse-lite@1.0.30001576:
resolution: {integrity: sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==}
dev: false
/electron-to-chromium@1.4.631:
resolution: {integrity: sha512-g73CJB/rMPjdxpiNJYmV1homV7mLVUNe/R0z/HhqMfpjkt58FpYmkTjbtuv3zymdbTTJ+VOEqe1c+lkTjSOhmQ==}
dev: false
/escalade@3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
dev: false
/node-releases@2.0.14:
resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
dev: false
/npx@10.2.2:
resolution: {integrity: sha512-eImmySusyeWphzs5iNh791XbZnZG0FSNvM4KSah34pdQQIDsdTDhIwg1sjN3AIVcjGLpbQ/YcfqHPshKZQK1fA==}
hasBin: true
dev: false
bundledDependencies:
- npm
- libnpx
/picocolors@1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: false
/update-browserslist-db@1.0.13(browserslist@4.22.2):
resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
dependencies:
browserslist: 4.22.2
escalade: 3.1.1
picocolors: 1.0.0
dev: false