Upgrading to Rails 5.2.3 (#891)

* Configurations update for rails 4.0

* ActiveSupport::Testing::Performance extracted to a gem

* ruby prof required as a dependency

* disable rubocop on bin folder

* http patch

* Comment out to allow testing

* no longer supports plugin loading

* lock to sprockets 2.12

* Active record patches

* remove deprecated test syntax

* fix failing tests

* change new super class

* replace right_aws with right_aws_api

right_aws is no longer maintained, was throwing an error

* lock to rails 4.2.11.1

* change rails version in install script

* remove deprecation warnings

* Change test lib to minitest, add  minitest reporters

* make app work

* active record find patches

* root_in_json include defaulted to false

* confirm option removed in link helper

* cookies serializer changed to hybrid

* Change render :text to :plain

render :text will be deprecated and poses a security risk

* console for dev web

* Check and fix interface functionality

* fix export functionality

* add protected attributes for the warpable model

* fix image upload

* Fix comments and images failing tests

* include mass assignment security in annotations

* render html for update images

* clear mail array before every test

* Fix codeclimate issues

* skip failing test

The test is failing because of different names in model(warpable) and
controller(images) skipping this for now until we decide if we want to
standardize the names

* replace unprotected redirects

* Fix codeclimate issues

* Autofixing rubocop offenses and Problematic test for #578 (#667)

* Autofixing rubocop offenses

* Adding Rubocop to Travis pipelines and development branch

* Fixing maps controller test

* Fixing remaining offenses

* change post test to create since action new is a get action

* remove unprotected redirects

* Fix codeclimate issues

* Add yarn

* Remove error log

* Fix oauth icons

* Modify package.json

* Add yarn install to start.sh

* Add leaflet google

* Remove leaflet-google from package json

* remove passenger error logs

* Fix install script

* Remove flag

* Fix gemfile.lock

* Fix gemfile.lock

* Fix login

* Upgrade Gemfile to Rails 5.0

* require rake'

* Change config files

* Add application record

* Bump mysql

* Local builds for Travis runners (#672)

* Using local mysql for travis

* Fix codeclimate issues

* Refactoring yamls

* Autofixing rubocop offenses and Problematic test for #578 (#667)

* Autofixing rubocop offenses

* Adding Rubocop to Travis pipelines and development branch

* Fixing maps controller test

* Fixing remaining offenses

* Fixing unit tests

* Adding docker build to travis pipelines

* Adding docker build to travis pipelines

* Staging builds in travis

* fix travis.yml

* Upgrading sintax of assets and using required gems

* Using updated version of GDAL and installing required dependencies

* Enabling cache in between builds

* Test yarn for travis

* Conditionalize rake db:setup for travis

* Add semicolon

* Remove comment

* modify database.yml

* Migrate seperately

* Run create only for production

* Locking newer Rails v

* Running update task

* Adding missing bootsnap gem

* Fixing missing database

* Adding missing listen gem

* Fixing schema example version

* Fixing migration versions

* Updating dependencies for Rails 5

* Adding ApplicationMailer abstraction

* Adding required initializers

* Prefer require_relative instead of full path

* Making associations not required by default

* Regenerating schema file

* Hotfixing MassAssigment

* Upgrade web-console, remove mysql adapter override

* Remove attr_accessible

* Add rails-controller-testing gem

* Follow new syntax for tests

* Remove extra web-console from gemfile

* Regenerating lock file

* Fixing rubocop offenses and bundler version

* Using correct Paperclip class as in https://github.com/rails/rails/issues/26404#issuecomment-502129936

* Fix images functional tests

* images controller test typecast to string

* Fix rails logger

* Fix map tests

* Bumping rubocop version

* Autofixing rubocop offenses

* Including performance cop to rubocop

* Refactoring deprecated routing and secret_token

* Fixing routes for feed controller

* Using correct routes for RSS builder

* Fixing missing routes

* Fixing travis bundler and yarn cache

* Fixing bundle path

* Splitting bundle and yarn verifications

* Autofixing rubocop offenses

* Fixing prod host for travis, private class usage and rubocop offenses

* Upgrade to Rails 5.2 (#685)

* Upgrade Gemfile to Rails 5.0

* require rake'

* Change config files

* Add application record

* Bump mysql

* Locking newer Rails v

* Running update task

* Adding missing bootsnap gem

* Fixing missing database

* Adding missing listen gem

* Fixing schema example version

* Fixing migration versions

* Updating dependencies for Rails 5

* Adding ApplicationMailer abstraction

* Adding required initializers

* Prefer require_relative instead of full path

* Making associations not required by default

* Regenerating schema file

* Hotfixing MassAssigment

* Upgrade web-console, remove mysql adapter override

* Remove attr_accessible

* Add rails-controller-testing gem

* Follow new syntax for tests

* Remove extra web-console from gemfile

* Regenerating lock file

* Fixing rubocop offenses and bundler version

* Using correct Paperclip class as in https://github.com/rails/rails/issues/26404#issuecomment-502129936

* Fix images functional tests

* images controller test typecast to string

* Fix rails logger

* Fix map tests

* Bumping rubocop version

* Autofixing rubocop offenses

* Including performance cop to rubocop

* Refactoring deprecated routing and secret_token

* Fixing routes for feed controller

* Using correct routes for RSS builder

* Fixing missing routes

* Fixing travis bundler and yarn cache

* Fixing bundle path

* Splitting bundle and yarn verifications

* Fixing prod host for travis, private class usage and rubocop offenses

* Enforcing params usage on get method

* Using correct folder names to Rails >5 conventions

* Enforcing params wrapping and adding missing front_ui route

* Precompiling assets before serving

* Improving Jenkins startup script

* Using supported docker yaml version by Jenkins

* Adding task to check database existance

* Improving start script

* Improving Makefile's recipes and target

* Adding task to check database existance

* Improving start script

* Improving Makefile's recipes and target

* Improving Makefile's recipes and target

* Patching https://github.com/publiclab/mapknitter/pull/803

* Improving Jenkins setup

* Fix map loading

* h

* Fixing Leaflet-Environmental-Layers map loading

* h

* leaflet

* fix

* change

* updates

* stop precompiling assets

* precompile

* Using correct Yarn, NPM and Node version, avoiding mismatch

* Removing unwanted tags.js invocation

* Improving Makefile recipe

* Using node_modules/ as dependencies folder, since https://github.com/sass/node-sass/issues/2050#issuecomment-317233552

* Upgrading Yarn dependencies

* Removing duplicate rubocop directive

* Removing test/ from codeclimate checks

* Removing fixed FIXME comments

* Removing fixed FIXME comments

* Updating docs in README

* Bumping recaptcha and include methods

* Fixing migration version

* Using strong params in requests

* Using strong params in requests

* Use Rack::Test::UploadedFile instead of ActionDispatch::Http::UploadedFile

* Remove rubocop linter

* Fix codeclimate issues

* Fix minor asset issue

* Remove manual asset references and add them to application js

* Fix asset ordering in application.js

* Configure System tests  (#936)

* Add new system tests and fix minor asset loading

* modify test

* Add chromedriver to travis

* Add sudo

* Add dependencies to dockerfile

* Properly installing chrome and chromedriver

* Fixing Map loading since merges
This commit is contained in:
Álax de Carvalho Alves
2019-08-15 16:59:45 -03:00
committed by Jeffrey Warren
parent 1281de8205
commit 27f8941a40
173 changed files with 5550 additions and 1584 deletions

View File

@@ -1,3 +0,0 @@
{
"directory": "./public/lib"
}

View File

@@ -17,8 +17,6 @@ plugins:
enabled: true
fixme:
enabled: true
rubocop:
enabled: true
exclude_patterns:
- config/
@@ -26,5 +24,6 @@ exclude_patterns:
- vendor/
- log/
- bin/
- test/

6
.gitignore vendored
View File

@@ -25,6 +25,7 @@ public/warpables/*
public/system/*
public/warps/*
public/tms/*
public/lib/*
db/schema.rb
*.db
config/database.yml
@@ -36,8 +37,7 @@ vendor/bundle
app/assets/bower_components
app/assets/node_modules
public/assets
public/lib
node_modules
node_modules/
todo.txt
.sass-cache
.byebug_history
@@ -46,3 +46,5 @@ test/reports/
yarn-error.log
yarn.lock
.idea/
passenger.3000.pid
passenger.3000.pid.lock

View File

@@ -1,3 +1,5 @@
require: rubocop-performance
# Start with Spotifys style guide as a base then customize from there
inherit_from:
- .rubocop_shopify_styleguide.yml
@@ -11,6 +13,7 @@ AllCops:
- '/config.ru'
Exclude:
- 'vendor/*'
- 'node_modules/**/*'
- 'spec/**/*'
- 'bin/*'
- 'doc/*'

View File

@@ -10,4 +10,5 @@ SimpleCov.start 'rails' do
add_filter '/vendor/'
add_filter '/log/'
add_filter '/tmp/'
add_filter '/node_modules/'
end

View File

@@ -1,24 +1,42 @@
language: ruby
rvm:
- 2.4.6
node_js:
- "12.6.0"
services:
- mysql
- docker
cache:
directories:
- $PWD/public/lib/
- $PWD/node_modules/
- $PWD/vendor/.bundle/
before_install:
- npm i -g npm@6.9.0
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.17.3
- export PATH="$HOME/.yarn/bin:$PATH"
install:
- cp config/database.yml.example config/database.yml
- cp config/config.yml.example config/config.yml
- cp db/schema.rb.example db/schema.rb
- ./lib/exporter-deps.sh > /dev/null 2>&1
- bundle check --path vendor/.bundle/ || bundle install --path vendor/.bundle/
- yarn check || yarn install
- bundle exec rake db:setup || bundle exec rake db:migrate
- if [ $RAILS_ENV != 'production' ]; then
yarn check || yarn install;
fi
- if [ $RAILS_ENV == 'production' ]; then
mysql -e "CREATE DATABASE mapknitter;";
mysql -e "CREATE USER 'mapknitter'@'%' IDENTIFIED BY 'mapknitter';";
mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'mapknitter'@'%';";
bundle exec rails db:schema:load;
else
bundle exec rails db:setup || bundle exec rails db:migrate;
fi
env:
global:
@@ -28,25 +46,26 @@ env:
jobs:
include:
- name: "Unit Tests"
script: bundle exec rake test:unit
- name: "Models Tests"
script: bundle exec rails test:models
- name: "Integration Tests"
script: bundle exec rake test:integration
- name: "Functional Tests"
script: bundle exec rake test:functional
script: bundle exec rails test:integration
- name: "Controllers Tests"
script: bundle exec rails test:controllers
- name: "System Tests"
script: bundle exec rails test:system
- name: "Rubocop Linter"
script: bundle exec rubocop
- name: "Docker Builds"
script: docker build -t mapknitter .
# Configure this option after full yarn setup
# - name: "Asset Precompilation"
# env:
# - RAILS_ENV=production
# script: bundle exec rake assets:precompile
- name: "Asset Precompilation"
env:
- RAILS_ENV=production
script:
- bundle exec rails assets:precompile
branches:
only:
- main
- unstable
- development

View File

@@ -1 +0,0 @@
--install.modules-folder "./public/lib"

View File

@@ -14,16 +14,33 @@ RUN echo "deb http://packages.laboratoriopublico.org/publiclab/ stretch main" >
COPY sysadmin.publiclab.key /app/sysadmin.publiclab.key
RUN apt-key add /app/sysadmin.publiclab.key
# Install dependencies
# Install dependencies for Mapknitter
RUN apt-get update -qq && apt-get install -y \
nodejs gdal-bin curl procps git imagemagick python-gdal zip
# Install dependencies for system tests
RUN apt-get -y install fonts-liberation libappindicator3-1 libasound2 \
libatk-bridge2.0-0 libatspi2.0-0 libgtk-3-0 libnspr4 \
libnss3 libx11-xcb1 libxss1 libxtst6 lsb-release xdg-utils && \
wget https://github.com/webnicer/chrome-downloads/raw/master/x64.deb/google-chrome-stable_75.0.3770.142-1_amd64.deb \
-O google-chrome.deb && \
dpkg -i google-chrome.deb && \
apt-get -fy install && \
wget https://chromedriver.storage.googleapis.com/74.0.3729.6/chromedriver_linux64.zip && \
unzip chromedriver_linux64.zip && \
mv chromedriver /usr/local/bin/chromedriver && \
chmod +x /usr/local/bin/chromedriver
# Configure ImageMagick
COPY ./nolimit.xml /etc/ImageMagick-6/policy.xml
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - && apt-get install -y npm
RUN npm install -g yarn
# See https://github.com/instructure/canvas-lms/issues/1404#issuecomment-461023483 and
# https://github.com/publiclab/mapknitter/pull/803
RUN git config --global url."https://".insteadOf git://
# Install bundle of gems
# Add the Rails app
COPY . /app/

67
Gemfile
View File

@@ -1,55 +1,60 @@
source "https://rubygems.org"
source 'https://rubygems.org'
ruby '2.4.6'
gem 'rails', '4.2.11.1'
gem 'rake', '~> 12.3.3'
gem 'rails', '~> 5.2.3'
gem 'rake', '~> 12.3.2'
gem 'tzinfo-data'
gem 'skylight'
gem "will_paginate", "3.1.7"
gem 'will_paginate-bootstrap4'
gem "friendly_id"
gem 'will_paginate', '3.1.7'
gem 'will_paginate-bootstrap4', '~> 0.2.2'
gem 'friendly_id'
gem 'popper_js', '~> 1.11', '>= 1.11.1'
gem 'protected_attributes'
gem 'paper_trail'
# dependencies
group :dependencies do
gem 'mysql2', '< 0.6'
gem "geokit-rails", "1.1.4"
gem 'geokit-rails', '1.1.4'
gem 'image_science', '1.3.0'
gem "recaptcha", :require => "recaptcha/rails"
gem "oa-openid", "0.3.2"
gem "ruby-openid", "~>2.5"
gem "open_id_authentication"
gem "RubyInline"
gem "paperclip", "~>4.3.7"
gem 'recaptcha', '~> 5.0.0', require: 'recaptcha/rails'
gem 'oa-openid', '0.3.2'
gem 'ruby-openid', '~>2.5'
gem 'open_id_authentication'
gem 'RubyInline', '~> 3.12.4'
gem 'paperclip', '~> 6.1.0'
gem 'bootsnap', '~> 1.4.4'
gem 'turbolinks', '~> 5'
gem 'mini_magick', '~> 4.8'
# if you use amazon s3 for warpable image storage
gem 'aws-sdk', '~> 1.5.7'
# for rake image migration tasks
# gem 'right_aws'
gem 'right_aws_api'
gem 'right_aws_api', '~> 0.3.5'
# compiling markdown to html
gem "rdiscount", "2.2.0.1"
gem 'rdiscount', '2.2.0.1'
# asset pipelining
gem 'bootstrap-sass'
gem 'sassc-rails'
gem 'jquery-rails'
gem "sprockets"
gem 'sprockets', '3.7.2'
gem "sprockets-rails"
gem "sass", :require => 'sass'
gem "autoprefixer-rails"
gem "uglifier"
gem 'sass', require: 'sass'
gem 'autoprefixer-rails', '~> 9.5.1.1'
gem 'uglifier', '~> 4.1.20'
end
group :test do
gem 'rubocop', '~> 0.52.0'
gem 'rubocop', '~> 0.70.0'
gem 'rubocop-performance'
gem 'ruby-prof'
gem 'rails-perftest'
gem 'rails-controller-testing'
gem 'simplecov', require: false
gem 'codecov', require: false
gem 'minitest'
@@ -57,25 +62,31 @@ group :test do
end
group :development, :test do
gem "byebug"
gem 'faker'
gem 'pry-rails'
gem 'capybara'
gem 'puma'
gem 'selenium-webdriver'
gem 'byebug', '~> 11.0.1', platforms: [:mri, :mingw, :x64_mingw]
gem 'faker', '~> 1.9.3'
gem 'pry-rails', '~> 0.3.9'
end
group :development do
gem "jshintrb"
gem "therubyracer"
gem 'jshintrb', '~> 0.3.0'
gem 'mini_racer', platforms: :ruby
gem 'listen', '~> 3.1.5'
gem 'web-console', '~> 3.3'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
group :sqlite do
# if you decide to use sqlite3 as the database
gem "sqlite3"
gem 'sqlite3'
end
group :passenger do
# passenger server
gem "passenger"
gem 'passenger'
end
gem 'httparty'

View File

@@ -4,58 +4,78 @@ GEM
RubyInline (3.12.4)
ZenTest (~> 4.3)
ZenTest (4.11.2)
actionmailer (4.2.11.1)
actionpack (= 4.2.11.1)
actionview (= 4.2.11.1)
activejob (= 4.2.11.1)
actioncable (5.2.3)
actionpack (= 5.2.3)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailer (5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (4.2.11.1)
actionview (= 4.2.11.1)
activesupport (= 4.2.11.1)
rack (~> 1.6)
rack-test (~> 0.6.2)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-dom-testing (~> 2.0)
actionpack (5.2.3)
actionview (= 5.2.3)
activesupport (= 5.2.3)
rack (~> 2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (4.2.11.1)
activesupport (= 4.2.11.1)
actionview (5.2.3)
activesupport (= 5.2.3)
builder (~> 3.1)
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
activejob (4.2.11.1)
activesupport (= 4.2.11.1)
globalid (>= 0.3.0)
activemodel (4.2.11.1)
activesupport (= 4.2.11.1)
builder (~> 3.1)
activerecord (4.2.11.1)
activemodel (= 4.2.11.1)
activesupport (= 4.2.11.1)
arel (~> 6.0)
activesupport (4.2.11.1)
i18n (~> 0.7)
activejob (5.2.3)
activesupport (= 5.2.3)
globalid (>= 0.3.6)
activemodel (5.2.3)
activesupport (= 5.2.3)
activerecord (5.2.3)
activemodel (= 5.2.3)
activesupport (= 5.2.3)
arel (>= 9.0)
activestorage (5.2.3)
actionpack (= 5.2.3)
activerecord (= 5.2.3)
marcel (~> 0.3.1)
activesupport (5.2.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
ansi (1.5.0)
arel (6.0.4)
arel (9.0.0)
ast (2.4.0)
autoprefixer-rails (9.6.1)
autoprefixer-rails (9.5.1.1)
execjs
aws-sdk (1.5.8)
httparty (~> 0.7)
json (~> 1.4)
nokogiri (>= 1.4.4)
uuidtools (~> 2.1)
bindex (0.8.1)
bootsnap (1.4.4)
msgpack (~> 1.0)
bootstrap-sass (3.4.1)
autoprefixer-rails (>= 5.2.1)
sassc (>= 2.0.0)
builder (3.2.3)
byebug (11.0.1)
capybara (3.28.0)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (~> 1.5)
xpath (~> 3.2)
childprocess (1.0.1)
rake (< 13.0)
climate_control (0.2.0)
cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0)
codecov (0.1.14)
json
simplecov
@@ -63,9 +83,8 @@ GEM
coderay (1.1.2)
concurrent-ruby (1.1.5)
crass (1.0.4)
debug_inspector (0.0.3)
docile (1.3.2)
erubis (2.7.0)
erubi (1.8.0)
execjs (2.7.0)
faker (1.9.6)
i18n (>= 0.7)
@@ -80,10 +99,11 @@ GEM
httparty (0.17.0)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
i18n (0.9.5)
i18n (1.6.0)
concurrent-ruby (~> 1.0)
image_science (1.3.0)
RubyInline (~> 3.9)
jaro_winkler (1.5.3)
jquery-rails (4.3.5)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
@@ -93,30 +113,41 @@ GEM
multi_json (>= 1.3)
rake
json (1.8.6)
libv8 (3.16.14.19)
libv8 (7.3.492.27.1)
libxml-ruby (3.1.0)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
loofah (2.2.3)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mini_mime (>= 0.1.1)
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (0.9.2)
mime-types (3.2.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2019.0331)
mimemagic (0.3.0)
mini_mime (1.0.1)
mimemagic (0.3.3)
mini_magick (4.9.5)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
mini_racer (0.2.6)
libv8 (>= 6.9.411)
minitest (5.11.3)
minitest-reporters (1.3.6)
ansi
builder
minitest (>= 5.0)
ruby-progressbar
msgpack (1.3.1)
multi_json (1.13.1)
multi_xml (0.6.0)
mysql2 (0.5.2)
net-http-persistent (2.9.4)
nio4r (2.4.0)
nokogiri (1.10.3)
mini_portile2 (~> 2.4.0)
oa-core (0.3.2)
@@ -126,15 +157,15 @@ GEM
ruby-openid-apps-discovery (~> 1.2.0)
open_id_authentication (1.3.0)
rack-openid (~> 1.3)
paper_trail (10.3.0)
activerecord (>= 4.2, < 6.1)
paper_trail (10.3.1)
activerecord (>= 4.2)
request_store (~> 1.1)
paperclip (4.3.7)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
cocaine (~> 0.5.5)
paperclip (6.1.0)
activemodel (>= 4.2.0)
activesupport (>= 4.2.0)
mime-types
mimemagic (= 0.3.0)
mimemagic (~> 0.3.0)
terrapin (~> 0.6.0)
parallel (1.17.0)
parser (2.6.3.0)
ast (~> 2.4.0)
@@ -142,55 +173,59 @@ GEM
rack
rake (>= 0.8.1)
popper_js (1.14.5)
powerpack (0.1.2)
protected_attributes (1.1.4)
activemodel (>= 4.0.1, < 5.0)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-rails (0.3.9)
pry (>= 0.10.4)
rack (1.6.11)
public_suffix (3.1.1)
puma (4.1.0)
nio4r (~> 2.0)
rack (2.0.7)
rack-openid (1.3.1)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-test (0.6.3)
rack (>= 1.0)
rails (4.2.11.1)
actionmailer (= 4.2.11.1)
actionpack (= 4.2.11.1)
actionview (= 4.2.11.1)
activejob (= 4.2.11.1)
activemodel (= 4.2.11.1)
activerecord (= 4.2.11.1)
activesupport (= 4.2.11.1)
bundler (>= 1.3.0, < 2.0)
railties (= 4.2.11.1)
sprockets-rails
rails-deprecated_sanitizer (1.0.3)
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.0.4)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.2.3)
actioncable (= 5.2.3)
actionmailer (= 5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
activemodel (= 5.2.3)
activerecord (= 5.2.3)
activestorage (= 5.2.3)
activesupport (= 5.2.3)
bundler (>= 1.3.0)
railties (= 5.2.3)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.4)
actionpack (>= 5.0.1.x)
actionview (>= 5.0.1.x)
activesupport (>= 5.0.1.x)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.1.0)
loofah (~> 2.2, >= 2.2.2)
rails-perftest (0.0.7)
railties (4.2.11.1)
actionpack (= 4.2.11.1)
activesupport (= 4.2.11.1)
railties (5.2.3)
actionpack (= 5.2.3)
activesupport (= 5.2.3)
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
thor (>= 0.19.0, < 2.0)
rainbow (3.0.0)
rake (12.3.3)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
rdiscount (2.2.0.1)
recaptcha (4.14.0)
recaptcha (5.0.0)
json
redcarpet (3.4.0)
ref (2.0.0)
redcarpet (3.5.0)
regexp_parser (1.6.0)
request_store (1.4.1)
rack (>= 1.4)
right_aws_api (0.3.5)
@@ -201,19 +236,23 @@ GEM
net-http-persistent (~> 2.9)
redcarpet (>= 3.0.0)
ruby-hmac (>= 0.4.0)
rubocop (0.52.1)
rubocop (0.70.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
parser (>= 2.4.0.2, < 3.0)
powerpack (~> 0.1)
parser (>= 2.6)
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
unicode-display_width (>= 1.4.0, < 1.7)
rubocop-performance (1.3.0)
rubocop (>= 0.68.0)
ruby-hmac (0.4.0)
ruby-openid (2.7.0)
ruby-openid-apps-discovery (1.2.0)
ruby-openid (>= 2.1.7)
ruby-prof (0.18.0)
ruby-prof (1.0.0)
ruby-progressbar (1.10.1)
ruby_dep (1.5.0)
rubyzip (1.2.3)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
@@ -228,7 +267,10 @@ GEM
sprockets (> 3.0)
sprockets-rails
tilt
simplecov (0.16.1)
selenium-webdriver (3.142.3)
childprocess (>= 0.5, < 2.0)
rubyzip (~> 1.2, >= 1.2.2)
simplecov (0.17.0)
docile (~> 1.1)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
@@ -237,6 +279,10 @@ GEM
skylight-core (= 4.1.2)
skylight-core (4.1.2)
activesupport (>= 4.2.0)
spring (2.1.0)
spring-watcher-listen (2.0.1)
listen (>= 2.7, < 4.0)
spring (>= 1.2, < 3.0)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
@@ -245,12 +291,14 @@ GEM
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.4.1)
therubyracer (0.12.3)
libv8 (~> 3.16.14.15)
ref
terrapin (0.6.0)
climate_control (>= 0.0.3, < 1.0)
thor (0.20.3)
thread_safe (0.3.6)
tilt (2.0.9)
turbolinks (5.2.0)
turbolinks-source (~> 5.2)
turbolinks-source (5.2.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
tzinfo-data (1.2019.2)
@@ -260,64 +308,80 @@ GEM
unicode-display_width (1.6.0)
url (0.3.2)
uuidtools (2.1.5)
web-console (3.3.0)
activemodel (>= 4.2)
debug_inspector
railties (>= 4.2)
web-console (3.7.0)
actionview (>= 5.0)
activemodel (>= 5.0)
bindex (>= 0.4.0)
railties (>= 5.0)
websocket-driver (0.7.1)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.4)
will_paginate (3.1.7)
will_paginate-bootstrap4 (0.2.2)
will_paginate (~> 3.0, >= 3.0.0)
xpath (3.2.0)
nokogiri (~> 1.8)
PLATFORMS
ruby
DEPENDENCIES
RubyInline
autoprefixer-rails
RubyInline (~> 3.12.4)
autoprefixer-rails (~> 9.5.1.1)
aws-sdk (~> 1.5.7)
bootsnap (~> 1.4.4)
bootstrap-sass
byebug
byebug (~> 11.0.1)
capybara
codecov
faker
faker (~> 1.9.3)
friendly_id
geokit-rails (= 1.1.4)
httparty
image_science (= 1.3.0)
jquery-rails
jshintrb
jshintrb (~> 0.3.0)
listen (~> 3.1.5)
mini_magick (~> 4.8)
mini_racer
minitest
minitest-reporters
mysql2 (< 0.6)
oa-openid (= 0.3.2)
open_id_authentication
paper_trail
paperclip (~> 4.3.7)
paperclip (~> 6.1.0)
passenger
popper_js (~> 1.11, >= 1.11.1)
protected_attributes
pry-rails
rails (= 4.2.11.1)
pry-rails (~> 0.3.9)
puma
rails (~> 5.2.3)
rails-controller-testing
rails-perftest
rake (~> 12.3.3)
rake (~> 12.3.2)
rdiscount (= 2.2.0.1)
recaptcha
right_aws_api
rubocop (~> 0.52.0)
recaptcha (~> 5.0.0)
right_aws_api (~> 0.3.5)
rubocop (~> 0.70.0)
rubocop-performance
ruby-openid (~> 2.5)
ruby-prof
sass
sassc-rails
selenium-webdriver
simplecov
skylight
sprockets
spring
spring-watcher-listen (~> 2.0.0)
sprockets (= 3.7.2)
sprockets-rails
sqlite3
therubyracer
turbolinks (~> 5)
tzinfo-data
uglifier
uglifier (~> 4.1.20)
web-console (~> 3.3)
will_paginate (= 3.1.7)
will_paginate-bootstrap4
will_paginate-bootstrap4 (~> 0.2.2)
RUBY VERSION
ruby 2.4.6p354

View File

@@ -1,17 +1,29 @@
export COMPOSE_HTTP_TIMEOUT=360
define wait_for_container
@while ! docker logs mapknitter | grep "web server started"; do\
echo "Serving Mapknitter";\
sleep 10;\
done;
endef
build:
cp config/database.yml.example config/database.yml
cp config/amazon_s3.yml.example config/amazon_s3.yml
cp config/config.yml.example config/config.yml
cp db/schema.rb.example db/schema.rb
docker-compose down --remove-orphans
docker-compose build
deploy-container:
docker-compose run --rm web bash -l -c "sleep 10 && bower install --allow-root && rake db:setup && rake db:migrate && rake assets:precompile"
docker-compose up -d
docker-compose exec -T web bash -l -c "sleep 10 && rake db:setup && rake db:migrate && rake assets:precompile"
$(call wait_for_container)
redeploy-container:
docker-compose down --remove-orphans
docker-compose up --force-recreate -d
docker-compose exec -T web bash -l -c "sleep 10 && rake db:migrate && rake assets:precompile"
$(call wait_for_container)
docker exec -e DISABLE_DATABASE_ENVIRONMENT_CHECK=1 mapknitter bash -lc \
"bundle exec rails db:drop && \
bundle exec rails db:create && \
bundle exec rails db:schema:load && \
bundle exec rails db:migrate"

View File

@@ -146,7 +146,7 @@ You'll need Ruby v2.4.6 (use your local ruby version management system - RVM / r
2. Install gems with `bundle install` from the rails root folder. You may need to run `bundle update` if you have older gems in your environment.
3. Copy and configure config/database.yml from config/database.yml.example, using a new empty database you've created
4. Copy and configure config/config.yml from config/config.yml.example (for now, this is only for the [Google Maps API Key, which is optional](http://stackoverflow.com/questions/2769148/whats-the-api-key-for-in-google-maps-api-v3), and a path for [logging in when running locally, also optional](#Logging-in-when-running-locally))
5. Initialize database with `bundle exec rake db:setup`
5. Initialize database with `bundle exec rails db:setup`
6. Enter ReCaptcha public and private keys in config/initializers/recaptcha.rb, copied from recaptcha.rb.example. To get keys, visit https://www.google.com/recaptcha/admin/create
7. Install static assets (like external javascript libraries, fonts) with `yarn install`
8. Start rails with `bundle exec passenger start` from the Rails root and open http://localhost:3000 in a web browser. (For some, just `passenger start` will work; adding `bundle exec` ensures you're using the version of passenger you just installed with Bundler.)
@@ -217,15 +217,11 @@ u_admin.role = 'admin'
When you try to run tests in MapKnitter, you can run the default Rake tasks, such as:
`rake test:units` `rake test:functionals` `rake test:integration`
`rails test:unit` `rails test:controllers` `rails test:integration`
or simply:
`rake test`
By running like this you'll see a lot of warnings and deprecation notices - FOR NOW -, but we're working on them. If you'd like a cleaner visual of your tests, you can just use our custom defined task:
`rake test:all`
`rails test`
#### Running tests of a specific file:

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env rake
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__)
require_relative 'config/application'
# Load all the rake tasks from the "tasks" folder.
task_dir = File.expand_path("../tasks", __FILE__)
@@ -9,4 +9,4 @@ Dir["#{task_dir}/**/*.rake"].each do |task_file|
load task_file
end
Mapknitter::Application.load_tasks
Rails.application.load_tasks

View File

@@ -1,4 +0,0 @@
//= require jquery/dist/jquery.js
//= require bootstrap/dist/js/bootstrap.js
//= require leaflet/dist/leaflet
//= require leaflet-providers/leaflet-providers.js

View File

@@ -1,5 +0,0 @@
//= require leaflet-draw/dist/leaflet.draw-src.js
//= require leaflet-illustrate/dist/Leaflet.Illustrate.js
//= require mapknitter/Annotations
//= require mapknitter/Annotations.style
//= require mapknitter/Annotations.Toolbar

View File

@@ -11,13 +11,14 @@
// GO AFTER THE REQUIRES BELOW.
//
//= require leaflet/dist/leaflet-src.js
//= require jquery
//= require jquery-ujs
//= require jquery/dist/jquery.js
//= require jquery-ujs/src/rails.js
//= require jquery-ui/jquery-ui.min.js
// = require leaflet/dist/leaflet-src.js
// = require jquery
// = require jquery-ujs
// = require jquery/dist/jquery.js
// = require jquery-ujs/src/rails.js
// = require jquery-ui/jquery-ui.min.js
//= require blueimp-tmpl/js/tmpl.js
//= require blueimp-file-upload/js/vendor/jquery.ui.widget
@@ -25,20 +26,22 @@
//= require blueimp-file-upload/js/jquery.fileupload-process
//= require blueimp-file-upload/js/jquery.fileupload-ui
//= require popper
//= require bootstrap/dist/js/bootstrap.js
// = require bootstrap/dist/js/bootstrap.js
//= require leaflet-providers/leaflet-providers.js
//= require leaflet-easybutton/src/easy-button.js
//= require leaflet-toolbar/dist/leaflet.toolbar.js
//= require leaflet-draw/dist/leaflet.draw-src.js
//= require leaflet-illustrate/dist/Leaflet.Illustrate.js
//= require leaflet-distortableimage/dist/leaflet.distortableimage.js
//= require leaflet-environmental-layers/dist/LeafletEnvironmentalLayers.js
//= require leaflet-environmental-layers/src/windRoseLayer.js
//= require Google.js
//= require sparklines/source/sparkline.js
//= require glfx-js/dist/glfx.js
//= require ion-rangeslider/js/ion.rangeSlider.js
//= require exif-js/exif.js
//= require webgl-distort/dist/webgl-distort.js
// = require leaflet-fullHash.js
// = require leaflet-providers/leaflet-providers.js
// = require leaflet-toolbar/dist/leaflet.toolbar.js
//= require leaflet-draw/dist/leaflet.draw-src.js
//= require leaflet-illustrate/dist/Leaflet.Illustrate.js
// = require leaflet-distortableimage/dist/leaflet.distortableimage.js
// = require leaflet-environmental-layers/dist/LeafletEnvironmentalLayers.js
// = require leaflet-environmental-layers/src/windRoseLayer.js
// = require leaflet-easybutton/src/easy-button.js
// = require sparklines/source/sparkline.js
// = require glfx-js/dist/glfx.js
// = require ion-rangeslider/js/ion.rangeSlider.js
// = require exif-js/exif.js
// = require webgl-distort/dist/webgl-distort.js
// = require mapknitter/core/Class.js
// = require_tree .

View File

@@ -1,418 +1,420 @@
// Legacy!
var Knitter = {
// start storing a layer_type and layer_url in Map model, use it to switch this:
openlayers_on: false,
save: {
state: true,
saved: function(response) {
Knitter.save.state = true
$('save_saved').show()
$('save_saving').hide()
$('save_failed').hide()
//console.log(response)
},
submitted: function(response) {
Knitter.save.state = "saving"
$('save_saved').hide()
$('save_saving').show()
$('save_failed').hide()
},
failed: function(response) {
Knitter.save.state = false
$('save_saved').hide()
$('save_saving').hide()
$('save_failed').show()
//console.log(response)
},
},
setup: function() {
Glop.observe('glop:predraw', function() { $C.clear();})
// disable default "delete" key (in Chrome it goes "back")
window.addEventListener ('keydown', function (e) {
// If the key pressed was a backspace key, handle it specially
if (e.keyIdentifier == 'U+0008' || e.keyIdentifier == 'Backspace') {
// If the target of the backspace was the body element, handle it specially
if (e.target == document.body) {
// Prevent the default Backspace action from happening
e.preventDefault ();
}
}
}, true);
var first_new_image = true
warpables.each(function(warpable,index) {
if (warpable.nodes != 'none') {
// nodes as [[lon,lat],[lon,lat]]
Warper.load_image(warpable.img,warpable.nodes,warpable.id,warpable.locked);
} else {
if (first_new_image) Warper.new_image(warpable.img,warpable.id,true);
else Warper.new_image(warpable.img,warpable.id,true)
first_new_image = false
}
})
Warper.sort_images()
Knitter.center_on_warpables()
if (Config.fullscreen) {
$('header').hide()
Config.padding_top = 0
}
if (Config.locked == 'true') {
Warper.locked = true
}
},
init_openlayers: function(format) {
if (format == 'WMS') {
map = new OpenLayers.Map('map', { controls: [],
projection: spher_merc,
displayProjection: spher_merc,
maxExtent: new OpenLayers.Bounds(-180,-90,180,90),
});
} else {
map = new OpenLayers.Map('map', { controls: [],
tileOrigin: new OpenLayers.LonLat(0,0).transform(latlon,spher_merc),
units: "m",
projection: latlon,
//numZoomLevels: 22,
displayProjection: spher_merc,
maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508.34),
//maxResolution: 156543.0339
});
}
Knitter.openlayers_on = true;
},
start_openlayers: function(layer,tile_url,tile_layer) {
if (layer == "none") $('map').hide()
else $('map').show()
if (!Knitter.openlayers_on) Knitter.init_openlayers(layer)
// http://isse.cr.usgs.gov/ArcGIS/services/Combined/TNM_Large_Scale_Imagery/MapServer/WMSServer?request=GetCapabilities&service=WMS
// http://raster.nationalmap.gov/ArcGIS/rest/services/Combined/TNM_Large_Scale_Imagery/MapServer
// http://viewer.nationalmap.gov/example/services.html
Config.tiles = true
Config.tile_type = layer
Zoom.interval = 6
if (layer == 'google') {
var gsat = new OpenLayers.Layer.Google("Google Satellite", {
type: google.maps.MapTypeId.SATELLITE,
sphericalMercator: true,
numZoomLevels: 23,
maxZoomLevel: 23
} );
map.addLayer(gsat)
map.layers[0].mapObject.setTilt(0);
// not sure why nothing else works, but this allows more zooming in!
map.layers[0].numZoomLevels = 24
map.layers[0].maxZoomLevel = 24
map.layers[0].resolutions.push(0.29858214168548586/2,0.29858214168548586/4,0.29858214168548586/8,0.29858214168548586/16)
map.setCenter(new OpenLayers.LonLat(10.2, 48.9).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 5);
} else if (layer == 'mapbox') {
var mapbox = new OpenLayers.Layer.TMS( "MapBox OpenStreetMap",
[ "http://a.tile.mapbox.com/","http://b.tile.mapbox.com/",
"http://c.tile.mapbox.com/","http://d.tile.mapbox.com/" ],
{ 'layername': 'mapbox.mapbox-streets', 'type':'jpg',
'buffer': 0, 'transitionEffect':'resize',
attribution: 'rendered by <a href="http://mapbox.com">MapBox</a>, from <a href="http://www.openstreetmap.org/">OpenStreetMap data</a>'} );
map.addLayer(mapbox)
} else if (layer == 'osm') {
var osm = new OpenLayers.Layer.TMS( "OpenStreetMap",
"http://tile.openstreetmap.org/",
{ type: 'png',
numZoomLevels: 23,
maxZoomLevel: 23,
getURL: osm_getTileURL,
displayOutsideMaxExtent: true,
attribution: '<a href="http://www.openstreetmap.org/">OpenStreetMap</a>'
}
);
map.addLayer(osm)
} else if (layer == 'bing') {
var apiKey = "AhYrUtF-jMIlTiblfgB_spQXBgc3u1_4h1mrgm_vEmyrnHLbA8v8452MolECULTX"
//Only in later versions of OpenLayers: //var bingsat = new OpenLayers.Layer.Bing("Aerial", {type: "Aerial", apiKey:apiKey, sphericalMercator:true});
var bingsat = new OpenLayers.Layer.VirtualEarth("Virtual Earth Aerial", {
'type': VEMapStyle.Aerial,
numZoomLevels: 23,
maxZoomLevel: 23,
'sphericalMercator': true
});
map.addLayer(bingsat)
} else if (layer == 'yahoo') {
var yahoosat = new OpenLayers.Layer.Yahoo("Yahoo Satellite", {type: YAHOO_MAP_SAT, sphericalMercator: true, numZoomLevels: 23});
map.addLayer(yahoosat)
/*you can try
http://hypercube.telascience.org/tilecache/tilecache.py/1.0.0/NAIP_ALL/
but you might get better performance from newworld which switches
between bmng/landsat/naip based on zoom level
http://hypercube.telascience.org/tilecache/tilecache.py/1.0.0/NewWorld_google */
} else if (layer == 'TMS') {
Config.tile_url = tile_url || Config.tile_url
var tms = new OpenLayers.Layer.TMS( "OpenLayers TMS", Config.tile_url,
{ //projection: latlon,
//displayProjection: spher_merc,
//getURL: Knitter.overlay_getTileURL,
//maxResolution:156543.0339,
//units: "m",
//maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508.34),
//tileOrigin: new OpenLayers.LonLat(0,0).transform(latlon,spher_merc),
numZoomLevels: 23,
serviceVersion: '.',
layername: '.',
type: 'png',
alpha: true,
isBaseLayer: true});
map.addLayer(tms);
} else if (layer == 'WMS') {
projection: latlon,
//wms_url = prompt('Enter a WMS URI','http://msrmaps.com/ogcmap.ashx')
Config.tile_url = tile_url || Config.tile_url
Config.tile_layer = tile_layer || Config.tile_layer
map.addLayer(new OpenLayers.Layer.WMS('WMS',Config.tile_url,{
layers: Config.tile_layer
//layers:'DOQ'
//layers:'osm'
}))
}
Glop.observe('glop:draw',function(){$('map').setStyle({height:Glop.height+'px'})})
if (Config.tile_type == 'WMS') Glop.observe('mouseup',function() {map.layers.first().refresh()})
// the following is complete nonsense and resolves to a point, not a bbox:
var lat1 = Projection.y_to_lat(Map.y-Glop.height/2)
var lon1 = Projection.x_to_lon(Map.x-Glop.width/2)
var lat2 = Projection.y_to_lat(Map.y+Glop.height/2)
var lon2 = Projection.x_to_lon(Map.x+Glop.width/2)
var bounds = new OpenLayers.Bounds();
bounds.extend(new OpenLayers.LonLat(lon1,lat1))//.transform(spher_merc,latlon))
bounds.extend(new OpenLayers.LonLat(lon2,lat2))//.transform(spher_merc,latlon))
//if (warpables.length = 0)
map.zoomToExtent( bounds )
//console.log(lat1,lon1,lat2,lon2)
//console.log(bounds)
//console.log('initial extent based on viewport sync with Cartagen')
//scalebar = new OpenLayers.Control.ScaleBar();
//map.addControl(scalebar);
if (Config.tile_switcher) {
var switcherControl = new OpenLayers.Control.LayerSwitcher()
map.addControl(switcherControl);
switcherControl.maximizeControl();
}
Knitter.openLayersDraw()
Glop.observe('glop:draw', Knitter.openLayersDraw)
//Knitter.update_map(Map.lat,Map.lon,Map.zoom,layer)
setTimeout(Knitter.update_map_to_center,1000)
},
update_map_to_center: function() {
loc = Knitter.find_map_center()
if (loc) Knitter.update_map(loc.lat,loc.lon,loc.zoom,false)
},
update_map: function(lat,lon,zoom,layer) {
Knitter.save.submitted()
layer = layer || false
new Ajax.Request('/map/update/'+Knitter.map_id,{
method: 'get',
parameters: {
map: {
lat: lat,
lon: lon
},
zoom: zoom,
tiles: layer,
tile_url: Config.tile_url,
tile_layer: Config.tile_layer
jQuery(document).ready(function($) {
var Knitter = {
// start storing a layer_type and layer_url in Map model, use it to switch this:
openlayers_on: false,
save: {
state: true,
saved: function(response) {
Knitter.save.state = true
$('save_saved').show()
$('save_saving').hide()
$('save_failed').hide()
//console.log(response)
},
onSuccess: Knitter.save.saved,
on0: Knitter.save.failed,
onFailure: Knitter.save.failed,
})
},
openLayersDraw: function() {
if (Config.tile_type == 'WMS') map.moveTo(new OpenLayers.LonLat(Map.lon,Map.lat))
else map.moveTo(new OpenLayers.LonLat(Map.lon,Map.lat).transform(spher_merc,latlon))
var left = new OpenLayers.LonLat(map.getExtent().left,map.getExtent().top);
var right = new OpenLayers.LonLat(map.getExtent().right,map.getExtent().bottom);
if (Config.tile_type == 'WMS') var convert = Glop.width/124023.4375
else {
left = left.transform(spher_merc,latlon);
right = right.transform(spher_merc,latlon);
var convert = 124023.4375*Glop.width
}
Map.zoom = convert/(right.lon-left.lon)
},
overlay_getTileURL: function(bounds) {
var res = this.map.getResolution();
var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
var y = Math.round((bounds.bottom - this.tileOrigin.lat) / (res * this.tileSize.h));
var z = this.map.getZoom();
//console.log('getting tile '+z+','+x+','+y)
if (this.map.baseLayer.name == 'Virtual Earth Roads' || this.map.baseLayer.name == 'Virtual Earth Aerial' || this.map.baseLayer.name == 'Virtual Earth Hybrid') {
z = z + 1;
submitted: function(response) {
Knitter.save.state = "saving"
$('save_saved').hide()
$('save_saving').show()
$('save_failed').hide()
},
failed: function(response) {
Knitter.save.state = false
$('save_saved').hide()
$('save_saving').hide()
$('save_failed').show()
//console.log(response)
},
},
setup: function() {
Glop.observe('glop:predraw', function() { $C.clear();})
// disable default "delete" key (in Chrome it goes "back")
window.addEventListener ('keydown', function (e) {
// If the key pressed was a backspace key, handle it specially
if (e.keyIdentifier == 'U+0008' || e.keyIdentifier == 'Backspace') {
// If the target of the backspace was the body element, handle it specially
if (e.target == document.body) {
// Prevent the default Backspace action from happening
e.preventDefault ();
}
if (mapBounds.intersectsBounds( bounds ) && z >= mapMinZoom && z <= mapMaxZoom ) {
//console.log( this.url + z + "/" + x + "/" + y + "." + this.type);
return this.url + z + "/" + x + "/" + y + "." + this.type;
} else {
return "http://www.maptiler.org/img/none.png";
}
},
save_new_location: function(lat,lon,zoom) {
Knitter.save.submitted()
new Ajax.Request('/map/update/'+Knitter.map_id,{
method: 'get',
parameters: {
lat: lat,
lon: lon,
zoom: zoom
},
onSuccess: Knitter.save.saved,
on0: Knitter.save.failed,
onFailure: Knitter.save.failed,
})
},
save_current_location: function(callback) {
Knitter.save_new_location(Map.lat,Map.lon,Map.zoom)
if (!Object.isUndefined(callback)) callback()
},
toggle_vectors: function() {
Config.vectors = !Config.vectors
$('tagreport').toggle()
if (Config.vectors) $('tool_vectors').addClassName('down')
else $('tool_vectors').removeClassName('down')
if ($('loading_message')) $('loading_message').hide()
Knitter.save.submitted()
new Ajax.Request('/map/update/'+Knitter.map_id,{
method: 'get',
parameters: {
lat: Map.lat,
lon: Map.lon,
zoom: Map.zoom,
vectors: Config.vectors
},
onSuccess: Knitter.save.saved,
on0: Knitter.save.failed,
onFailure: Knitter.save.failed,
})
},
background_transparent: true,
toggle_background: function() {
if (Knitter.background_transparent) {
$('map').removeClassName('transparent');
} else {
$('map').addClassName('transparent');
}
Knitter.background_transparent = !Knitter.background_transparent
},
find_map_center: function() {
if (warpables.length > 0) {
var latsum = 0, lonsum = 0, latcount = 0, loncount = 0
var maxlat = 0,maxlon = 0,minlat = 0,minlon = 0
warpables.each(function(warpable){
if (warpable.nodes != "none") {
warpable.nodes.each(function(node) {
var lon = Projection.x_to_lon(-node[0])
var lat = Projection.y_to_lat(node[1])
if (maxlon == 0) maxlon = lon
if (maxlat == 0) maxlat = lat
if (minlon == 0) minlon = lon
if (minlat == 0) minlat = lat
if (lon > maxlon) maxlon = lon
if (lat > maxlat) maxlat = lat
if (lon < minlon) minlon = lon
if (lat < minlat) minlat = lat
lonsum += lon
latsum += lat
loncount += 1
latcount += 1
})
}
},this)
zoom = parseInt(-Math.log((maxlon-minlon)/360)/Math.log(2))+2
if (loncount) {
return { lat:(maxlat+minlat)/2,
lon:(maxlon+minlon)/2,
zoom:zoom,
width:maxlon-minlon
}, true);
var first_new_image = true
warpables.each(function(warpable,index) {
if (warpable.nodes != 'none') {
// nodes as [[lon,lat],[lon,lat]]
Warper.load_image(warpable.img,warpable.nodes,warpable.id,warpable.locked);
} else {
if (first_new_image) Warper.new_image(warpable.img,warpable.id,true);
else Warper.new_image(warpable.img,warpable.id,true)
first_new_image = false
}
} else {
return false
})
Warper.sort_images()
Knitter.center_on_warpables()
if (Config.fullscreen) {
$('header').hide()
Config.padding_top = 0
}
} else { return false }
},
if (Config.locked == 'true') {
Warper.locked = true
}
},
init_openlayers: function(format) {
if (format == 'WMS') {
map = new OpenLayers.Map('map', { controls: [],
projection: spher_merc,
displayProjection: spher_merc,
maxExtent: new OpenLayers.Bounds(-180,-90,180,90),
});
} else {
map = new OpenLayers.Map('map', { controls: [],
tileOrigin: new OpenLayers.LonLat(0,0).transform(latlon,spher_merc),
units: "m",
projection: latlon,
//numZoomLevels: 22,
displayProjection: spher_merc,
maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508.34),
//maxResolution: 156543.0339
});
}
Knitter.openlayers_on = true;
},
center_on_warpables: function() {
loc = Knitter.find_map_center()
if (loc) Cartagen.go_to(loc.lat,loc.lon,loc.zoom)
// the "+2" is a hack... this equation would work without it if the map were only one tile wide.
map.zoomTo(parseInt(-Math.log((loc.width)/360)/Math.log(2))+2)
},
start_openlayers: function(layer,tile_url,tile_layer) {
if (layer == "none") $('map').hide()
else $('map').show()
if (!Knitter.openlayers_on) Knitter.init_openlayers(layer)
// http://isse.cr.usgs.gov/ArcGIS/services/Combined/TNM_Large_Scale_Imagery/MapServer/WMSServer?request=GetCapabilities&service=WMS
// http://raster.nationalmap.gov/ArcGIS/rest/services/Combined/TNM_Large_Scale_Imagery/MapServer
// http://viewer.nationalmap.gov/example/services.html
Config.tiles = true
Config.tile_type = layer
Zoom.interval = 6
if (layer == 'google') {
var gsat = new OpenLayers.Layer.Google("Google Satellite", {
type: google.maps.MapTypeId.SATELLITE,
sphericalMercator: true,
numZoomLevels: 23,
maxZoomLevel: 23
} );
map.addLayer(gsat)
map.layers[0].mapObject.setTilt(0);
export_tabs: ['export_intro','export_options'],
export_hide_tabs: function() {
Knitter.export_tabs.each(function(tab) {
$(tab).hide();
$(tab+'_tab').removeClassName('active');
})
},
export_intro: function() {
Knitter.export_hide_tabs();
$('export_normal').show();
$('export_intro').show();
$('export_intro_tab').addClassName('active');
},
export_options: function() {
Knitter.export_hide_tabs();
$('export_normal').show();
$('export_options').show();
$('export_options_tab').addClassName('active');
},
export_multispectral: function() {
Knitter.export_hide_tabs();
$('export_normal').hide();
$('export_multispectral').show();
$('export_multispectral_tab').addClassName('active');
},
// for now, just used to store the "export progress" checkers, which run every 5 secs and fill up the logs.
updaters: [],
cancel_updaters: function() {
Knitter.updaters.each(function(u){
u.stop()
})
},
}
// not sure why nothing else works, but this allows more zooming in!
map.layers[0].numZoomLevels = 24
map.layers[0].maxZoomLevel = 24
map.layers[0].resolutions.push(0.29858214168548586/2,0.29858214168548586/4,0.29858214168548586/8,0.29858214168548586/16)
map.setCenter(new OpenLayers.LonLat(10.2, 48.9).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 5);
function osm_getTileURL(bounds) {
var res = this.map.getResolution();
var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
var z = this.map.getZoom();
var limit = Math.pow(2, z);
} else if (layer == 'mapbox') {
var mapbox = new OpenLayers.Layer.TMS( "MapBox OpenStreetMap",
[ "http://a.tile.mapbox.com/","http://b.tile.mapbox.com/",
"http://c.tile.mapbox.com/","http://d.tile.mapbox.com/" ],
{ 'layername': 'mapbox.mapbox-streets', 'type':'jpg',
'buffer': 0, 'transitionEffect':'resize',
attribution: 'rendered by <a href="http://mapbox.com">MapBox</a>, from <a href="http://www.openstreetmap.org/">OpenStreetMap data</a>'} );
map.addLayer(mapbox)
} else if (layer == 'osm') {
var osm = new OpenLayers.Layer.TMS( "OpenStreetMap",
"http://tile.openstreetmap.org/",
{ type: 'png',
numZoomLevels: 23,
maxZoomLevel: 23,
getURL: osm_getTileURL,
displayOutsideMaxExtent: true,
attribution: '<a href="http://www.openstreetmap.org/">OpenStreetMap</a>'
}
);
map.addLayer(osm)
} else if (layer == 'bing') {
var apiKey = "AhYrUtF-jMIlTiblfgB_spQXBgc3u1_4h1mrgm_vEmyrnHLbA8v8452MolECULTX"
//Only in later versions of OpenLayers: //var bingsat = new OpenLayers.Layer.Bing("Aerial", {type: "Aerial", apiKey:apiKey, sphericalMercator:true});
var bingsat = new OpenLayers.Layer.VirtualEarth("Virtual Earth Aerial", {
'type': VEMapStyle.Aerial,
numZoomLevels: 23,
maxZoomLevel: 23,
'sphericalMercator': true
});
map.addLayer(bingsat)
} else if (layer == 'yahoo') {
var yahoosat = new OpenLayers.Layer.Yahoo("Yahoo Satellite", {type: YAHOO_MAP_SAT, sphericalMercator: true, numZoomLevels: 23});
map.addLayer(yahoosat)
/*you can try
http://hypercube.telascience.org/tilecache/tilecache.py/1.0.0/NAIP_ALL/
if (y < 0 || y >= limit) {
return "http://www.maptiler.org/img/none.png";
} else {
x = ((x % limit) + limit) % limit;
return this.url + z + "/" + x + "/" + y + "." + this.type;
but you might get better performance from newworld which switches
between bmng/landsat/naip based on zoom level
http://hypercube.telascience.org/tilecache/tilecache.py/1.0.0/NewWorld_google */
} else if (layer == 'TMS') {
Config.tile_url = tile_url || Config.tile_url
var tms = new OpenLayers.Layer.TMS( "OpenLayers TMS", Config.tile_url,
{ //projection: latlon,
//displayProjection: spher_merc,
//getURL: Knitter.overlay_getTileURL,
//maxResolution:156543.0339,
//units: "m",
//maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508.34),
//tileOrigin: new OpenLayers.LonLat(0,0).transform(latlon,spher_merc),
numZoomLevels: 23,
serviceVersion: '.',
layername: '.',
type: 'png',
alpha: true,
isBaseLayer: true});
map.addLayer(tms);
} else if (layer == 'WMS') {
projection: latlon,
//wms_url = prompt('Enter a WMS URI','http://msrmaps.com/ogcmap.ashx')
Config.tile_url = tile_url || Config.tile_url
Config.tile_layer = tile_layer || Config.tile_layer
map.addLayer(new OpenLayers.Layer.WMS('WMS',Config.tile_url,{
layers: Config.tile_layer
//layers:'DOQ'
//layers:'osm'
}))
}
Glop.observe('glop:draw',function(){$('map').setStyle({height:Glop.height+'px'})})
if (Config.tile_type == 'WMS') Glop.observe('mouseup',function() {map.layers.first().refresh()})
// the following is complete nonsense and resolves to a point, not a bbox:
var lat1 = Projection.y_to_lat(Map.y-Glop.height/2)
var lon1 = Projection.x_to_lon(Map.x-Glop.width/2)
var lat2 = Projection.y_to_lat(Map.y+Glop.height/2)
var lon2 = Projection.x_to_lon(Map.x+Glop.width/2)
var bounds = new OpenLayers.Bounds();
bounds.extend(new OpenLayers.LonLat(lon1,lat1))//.transform(spher_merc,latlon))
bounds.extend(new OpenLayers.LonLat(lon2,lat2))//.transform(spher_merc,latlon))
//if (warpables.length = 0)
map.zoomToExtent( bounds )
//console.log(lat1,lon1,lat2,lon2)
//console.log(bounds)
//console.log('initial extent based on viewport sync with Cartagen')
//scalebar = new OpenLayers.Control.ScaleBar();
//map.addControl(scalebar);
if (Config.tile_switcher) {
var switcherControl = new OpenLayers.Control.LayerSwitcher()
map.addControl(switcherControl);
switcherControl.maximizeControl();
}
Knitter.openLayersDraw()
Glop.observe('glop:draw', Knitter.openLayersDraw)
//Knitter.update_map(Map.lat,Map.lon,Map.zoom,layer)
setTimeout(Knitter.update_map_to_center,1000)
},
update_map_to_center: function() {
loc = Knitter.find_map_center()
if (loc) Knitter.update_map(loc.lat,loc.lon,loc.zoom,false)
},
update_map: function(lat,lon,zoom,layer) {
Knitter.save.submitted()
layer = layer || false
new Ajax.Request('/map/update/'+Knitter.map_id,{
method: 'get',
parameters: {
map: {
lat: lat,
lon: lon
},
zoom: zoom,
tiles: layer,
tile_url: Config.tile_url,
tile_layer: Config.tile_layer
},
onSuccess: Knitter.save.saved,
on0: Knitter.save.failed,
onFailure: Knitter.save.failed,
})
},
openLayersDraw: function() {
if (Config.tile_type == 'WMS') map.moveTo(new OpenLayers.LonLat(Map.lon,Map.lat))
else map.moveTo(new OpenLayers.LonLat(Map.lon,Map.lat).transform(spher_merc,latlon))
var left = new OpenLayers.LonLat(map.getExtent().left,map.getExtent().top);
var right = new OpenLayers.LonLat(map.getExtent().right,map.getExtent().bottom);
if (Config.tile_type == 'WMS') var convert = Glop.width/124023.4375
else {
left = left.transform(spher_merc,latlon);
right = right.transform(spher_merc,latlon);
var convert = 124023.4375*Glop.width
}
Map.zoom = convert/(right.lon-left.lon)
},
overlay_getTileURL: function(bounds) {
var res = this.map.getResolution();
var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
var y = Math.round((bounds.bottom - this.tileOrigin.lat) / (res * this.tileSize.h));
var z = this.map.getZoom();
//console.log('getting tile '+z+','+x+','+y)
if (this.map.baseLayer.name == 'Virtual Earth Roads' || this.map.baseLayer.name == 'Virtual Earth Aerial' || this.map.baseLayer.name == 'Virtual Earth Hybrid') {
z = z + 1;
}
if (mapBounds.intersectsBounds( bounds ) && z >= mapMinZoom && z <= mapMaxZoom ) {
//console.log( this.url + z + "/" + x + "/" + y + "." + this.type);
return this.url + z + "/" + x + "/" + y + "." + this.type;
} else {
return "http://www.maptiler.org/img/none.png";
}
},
save_new_location: function(lat,lon,zoom) {
Knitter.save.submitted()
new Ajax.Request('/map/update/'+Knitter.map_id,{
method: 'get',
parameters: {
lat: lat,
lon: lon,
zoom: zoom
},
onSuccess: Knitter.save.saved,
on0: Knitter.save.failed,
onFailure: Knitter.save.failed,
})
},
save_current_location: function(callback) {
Knitter.save_new_location(Map.lat,Map.lon,Map.zoom)
if (!Object.isUndefined(callback)) callback()
},
toggle_vectors: function() {
Config.vectors = !Config.vectors
$('tagreport').toggle()
if (Config.vectors) $('tool_vectors').addClassName('down')
else $('tool_vectors').removeClassName('down')
if ($('loading_message')) $('loading_message').hide()
Knitter.save.submitted()
new Ajax.Request('/map/update/'+Knitter.map_id,{
method: 'get',
parameters: {
lat: Map.lat,
lon: Map.lon,
zoom: Map.zoom,
vectors: Config.vectors
},
onSuccess: Knitter.save.saved,
on0: Knitter.save.failed,
onFailure: Knitter.save.failed,
})
},
background_transparent: true,
toggle_background: function() {
if (Knitter.background_transparent) {
$('map').removeClassName('transparent');
} else {
$('map').addClassName('transparent');
}
Knitter.background_transparent = !Knitter.background_transparent
},
find_map_center: function() {
if (warpables.length > 0) {
var latsum = 0, lonsum = 0, latcount = 0, loncount = 0
var maxlat = 0,maxlon = 0,minlat = 0,minlon = 0
warpables.each(function(warpable){
if (warpable.nodes != "none") {
warpable.nodes.each(function(node) {
var lon = Projection.x_to_lon(-node[0])
var lat = Projection.y_to_lat(node[1])
if (maxlon == 0) maxlon = lon
if (maxlat == 0) maxlat = lat
if (minlon == 0) minlon = lon
if (minlat == 0) minlat = lat
if (lon > maxlon) maxlon = lon
if (lat > maxlat) maxlat = lat
if (lon < minlon) minlon = lon
if (lat < minlat) minlat = lat
lonsum += lon
latsum += lat
loncount += 1
latcount += 1
})
}
},this)
zoom = parseInt(-Math.log((maxlon-minlon)/360)/Math.log(2))+2
if (loncount) {
return { lat:(maxlat+minlat)/2,
lon:(maxlon+minlon)/2,
zoom:zoom,
width:maxlon-minlon
}
} else {
return false
}
} else { return false }
},
center_on_warpables: function() {
loc = Knitter.find_map_center()
if (loc) Cartagen.go_to(loc.lat,loc.lon,loc.zoom)
// the "+2" is a hack... this equation would work without it if the map were only one tile wide.
map.zoomTo(parseInt(-Math.log((loc.width)/360)/Math.log(2))+2)
},
export_tabs: ['export_intro','export_options'],
export_hide_tabs: function() {
Knitter.export_tabs.each(function(tab) {
$(tab).hide();
$(tab+'_tab').removeClassName('active');
})
},
export_intro: function() {
Knitter.export_hide_tabs();
$('export_normal').show();
$('export_intro').show();
$('export_intro_tab').addClassName('active');
},
export_options: function() {
Knitter.export_hide_tabs();
$('export_normal').show();
$('export_options').show();
$('export_options_tab').addClassName('active');
},
export_multispectral: function() {
Knitter.export_hide_tabs();
$('export_normal').hide();
$('export_multispectral').show();
$('export_multispectral_tab').addClassName('active');
},
// for now, just used to store the "export progress" checkers, which run every 5 secs and fill up the logs.
updaters: [],
cancel_updaters: function() {
Knitter.updaters.each(function(u){
u.stop()
})
},
}
}
function osm_getTileURL(bounds) {
var res = this.map.getResolution();
var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
var z = this.map.getZoom();
var limit = Math.pow(2, z);
if (y < 0 || y >= limit) {
return "http://www.maptiler.org/img/none.png";
} else {
x = ((x % limit) + limit) % limit;
return this.url + z + "/" + x + "/" + y + "." + this.type;
}
}
});

View File

@@ -3,8 +3,8 @@ MapKnitter.Annotations.include({
initialize: function(options) {
MapKnitter.Resources.prototype.initialize.call(this, options);
var map = options.map
drawOptions = {};
var map = options.map,
drawOptions = {};
this._map = map;
this._drawnItems = new L.FeatureGroup().addTo(map);

View File

@@ -1,5 +1,3 @@
//= require leaflet-toolbar/dist/leaflet.toolbar.js
//= require leaflet-distortableimage/dist/leaflet.distortableimage.js
MapKnitter.Map = MapKnitter.Class.extend({
@@ -412,8 +410,8 @@ MapKnitter.Map = MapKnitter.Class.extend({
// reset change state string:
img._corner_state = JSON.stringify(img._corners);
// send save request
$.ajax('/images/update', {
type: 'POST',
$.ajax('/images', {
type: 'PATCH',
data: {
warpable_id: img.warpable_id,
locked: (img.editing._mode == 'lock'),

View File

@@ -5,6 +5,7 @@
//= require ion-rangeslider/js/ion.rangeSlider.js
/* Move navbar links into dropdown if nav is inside the sidebar. */
// = require jquery/dist/jquery.js
jQuery(document).ready(function($) {
window.toggle_sidebar = function() {
var icon = $('.sidebar-toggle-icon');

View File

@@ -11,6 +11,7 @@ $icon-font-path: "bootstrap-sass/assets/fonts/bootstrap/";
@import "leaflet-illustrate/dist/Leaflet.Illustrate.css";
@import "leaflet-toolbar/dist/leaflet.toolbar.css";
@import "leaflet-distortableimage/dist/leaflet.distortableimage.css";
@import "leaflet-environmental-layers/dist/LeafletEnvironmentalLayers.css";
@import "@fortawesome/fontawesome-free/css/all.css";
// /*
// * This is a manifest file that'll be compiled into application.css, which will include all the files

View File

@@ -1,8 +1,8 @@
require 'json'
class AnnotationsController < ApplicationController
# before_filter :require_user, :except => [ :index, :show ]
before_filter :find_map
# before_action :require_user, :except => [ :index, :show ]
before_action :find_map
def index
render file: 'annotations/index.json.erb', content_type: 'application/json'
@@ -36,9 +36,9 @@ class AnnotationsController < ApplicationController
return if @annotation.user_id.nil? || current_user.can_edit?(@annotation)
Annotation.update(@annotation.id,
coordinates: geojson[:geometry][:coordinates],
text: geojson[:properties][:textContent],
style: geojson[:properties][:style])
coordinates: geojson[:geometry][:coordinates],
text: geojson[:properties][:textContent],
style: geojson[:properties][:style])
render file: 'annotations/update.json.erb',
content_type: 'application/json'
end

View File

@@ -6,7 +6,7 @@ class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
before_filter :current_user
before_action :current_user
helper_method :logged_in?, :current_location
before_action :set_paper_trail_whodunnit

View File

@@ -17,7 +17,7 @@ class ExportController < ApplicationController
if params[:action] == 'progress'
nil
else
RAILS_DEFAULT_LOGGER
Rails.logger
end
end

View File

@@ -1,5 +1,5 @@
class FeedsController < ApplicationController
before_filter :query, only: %i(clean license)
before_action :query, only: %i(clean license)
def all
# (Warpable.all + Map.all).sort_by(&:created_at)

View File

@@ -8,9 +8,12 @@ class FrontUiController < ApplicationController
@maps = Map.new_maps.first(4)
@unpaginated = true
# TODO: these could use optimization but are better than prev:
tag = Tag.where(name: 'featured').first # note that this is not a join table but the .maps method still works
@mappers = User.where(login: tag.maps.collect(&:author)) if tag
@mappers ||= []
tag = Tag.where(name: 'featured').first
@mappers = if tag
User.where(login: tag.maps.collect(&:author))
else
[]
end
end
def all_maps
@@ -19,6 +22,7 @@ class FrontUiController < ApplicationController
def nearby_mappers
return unless current_location.present?
lat = session[:lat]
lon = session[:lon]
@nearby_maps = Map.maps_nearby(lat: lat, lon: lon, dist: 10)

View File

@@ -1,8 +1,8 @@
require 'open-uri'
class ImagesController < ApplicationController
rescue_from Errno::ENOENT, Errno::ETIMEDOUT,
OpenURI::HTTPError, Timeout::Error,
with: :url_upload_not_found
OpenURI::HTTPError, Timeout::Error,
with: :url_upload_not_found
protect_from_forgery except: %i(update delete)
# Convert model to json without including root name. Eg. 'warpable'
ActiveRecord::Base.include_root_in_json = false

View File

@@ -3,8 +3,8 @@ require 'open3'
class MapsController < ApplicationController
protect_from_forgery except: :export
before_filter :require_login, only: %i(edit update destroy)
before_filter :find_map, only: %i(show annotate embed edit update images destroy archive)
before_action :require_login, only: %i(edit update destroy)
before_action :find_map, only: %i(show annotate embed edit update images destroy archive)
layout 'knitter2'

View File

@@ -1,5 +1,5 @@
class TagsController < ApplicationController
before_filter :require_login, only: %i(edit update destroy)
before_action :require_login, only: %i(edit update destroy)
def create
@map = Map.find_by(slug: params[:map_id])

View File

@@ -30,6 +30,6 @@ class UsersController < ApplicationController
def user_params
params.require(:user).permit(:login, :email, :name,
:password, :password_confirmation)
:password, :password_confirmation)
end
end

View File

@@ -41,8 +41,8 @@ module ApplicationHelper
# see https://github.com/rails/jquery-ujs/wiki/Manual-installing-and-Rails-2
def csrf_meta_tags
if protect_against_forgery?
out = %(<meta name="csrf-param" content="%s"/>\n) # rubocop:disable Style/FormatStringToken
out << %(<meta name="csrf-token" content="%s"/>) # rubocop:disable Style/FormatStringToken
out = %(<meta name="csrf-param" content="%s"/>\n)
out << %(<meta name="csrf-token" content="%s"/>)
format(out, Rack::Utils.escape_html(request_forgery_protection_token), Rack::Utils.escape_html(form_authenticity_token))
end
end

View File

@@ -0,0 +1,4 @@
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
layout 'mailer'
end

View File

@@ -1,4 +1,4 @@
class CommentMailer < ActionMailer::Base
class CommentMailer < ApplicationMailer
default from: "do-not-reply@mapknitter.org"
# CommentMailer.notify_of_comment(user,self).deliver

View File

@@ -1,9 +1,8 @@
class Annotation < ActiveRecord::Base
include ActiveModel::MassAssignmentSecurity
belongs_to :map
belongs_to :user
class Annotation < ApplicationRecord
belongs_to :map, optional: true
belongs_to :user, optional: true
attr_accessible :annotation_type, :coordinates, :text, :style
attr_accessor :annotation_type, :coordinates, :text, :style
serialize :coordinates, Array
serialize :style, Hash

View File

@@ -0,0 +1,3 @@
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end

View File

@@ -1,6 +1,6 @@
class Comment < ActiveRecord::Base
belongs_to :map
belongs_to :user
class Comment < ApplicationRecord
belongs_to :map, optional: true
belongs_to :user, optional: true
validates_presence_of :body, :user_id, :map_id

View File

@@ -1,6 +1,6 @@
class Export < ActiveRecord::Base
belongs_to :map
belongs_to :user
class Export < ApplicationRecord
belongs_to :map, optional: true
belongs_to :user, optional: true
# currently exporting?
def running?
@@ -52,12 +52,12 @@ class Export < ActiveRecord::Base
def self.export_count
Export.where('status != "failed" AND status != "complete" AND status != "none" AND updated_at > ?',
(DateTime.now - 24.hours).to_s(:db)).count
(DateTime.now - 24.hours).to_s(:db)).count
end
# all exports currently running
def self.exporting
Export.where('status != "failed" AND status != "complete" AND status != "none" AND updated_at > ?',
(DateTime.now - 24.hours).to_s(:db))
(DateTime.now - 24.hours).to_s(:db))
end
end

View File

@@ -1,4 +1,4 @@
class Map < ActiveRecord::Base
class Map < ApplicationRecord
include ActiveModel::Validations
extend FriendlyId
friendly_id :name, use: %i(slugged static)
@@ -20,7 +20,7 @@ class Map < ActiveRecord::Base
has_many :tags, dependent: :destroy
has_many :comments, dependent: :destroy
has_many :annotations, dependent: :destroy
belongs_to :user
belongs_to :user, optional: true
has_many :warpables
scope :active, -> { where(archived: false) }
@@ -150,7 +150,7 @@ class Map < ActiveRecord::Base
return [] if lat.to_f == 0.0 || lon.to_f == 0.0
Map.where('id != ? AND lat > ? AND lat < ? AND lon > ? AND lon < ?',
id, lat - dist, lat + dist, lon - dist, lon + dist)
id, lat - dist, lat + dist, lon - dist, lon + dist)
.limit(10)
end
@@ -240,14 +240,14 @@ class Map < ActiveRecord::Base
new_export = Export.new(map_id: id) unless export
Exporter.run_export(user,
resolution,
export || new_export,
id,
slug,
Rails.root.to_s,
average_scale,
placed_warpables,
key)
resolution,
export || new_export,
id,
slug,
Rails.root.to_s,
average_scale,
placed_warpables,
key)
end
def after_create

View File

@@ -1,3 +1,3 @@
class Node < ActiveRecord::Base
belongs_to :way
class Node < ApplicationRecord
belongs_to :way, optional: true
end

View File

@@ -1,6 +1,6 @@
class Tag < ActiveRecord::Base
belongs_to :map
belongs_to :user
class Tag < ApplicationRecord
belongs_to :map, optional: true
belongs_to :user, optional: true
validates_presence_of :name, on: :create, message: "can't be blank"
validates_presence_of :user_id, on: :create, message: "can't be blank"

View File

@@ -1,6 +1,6 @@
require 'digest/sha1'
class User < ActiveRecord::Base
class User < ApplicationRecord
has_many :maps
has_many :tags
has_many :comments
@@ -16,8 +16,7 @@ class User < ActiveRecord::Base
validates_length_of :email, within: 6..100 # r@a.wk
validates_uniqueness_of :email
# HACK: HACK HACK -- how to do attr_accessible from here?
# prevents a user from submitting a crafted form that bypasses activation
# Prevents a user from submitting a crafted form that bypasses activation
# anything else you want your user to change should be added here.
# Authenticates a user by their login name and unencrypted password. Returns the user or nil.

View File

@@ -1,22 +1,21 @@
class Warpable < ActiveRecord::Base
include ActiveModel::MassAssignmentSecurity
attr_accessible :image
class Warpable < ApplicationRecord
attr_accessor :image
attr_accessor :src, :srcmedium # for json generation
# Paperclip; config and production/development specific configs
# in /config/initializers/paperclip.rb
has_attached_file :image,
s3_protocol: 'https',
styles: {
medium: "500x375",
small: "240x180",
thumb: "100x100>"
}
s3_protocol: 'https',
styles: {
medium: "500x375",
small: "240x180",
thumb: "100x100>"
}
validates_attachment_content_type :image, content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"]
belongs_to :map
belongs_to :user
belongs_to :map, optional: true
belongs_to :user, optional: true
has_paper_trail on: %i(create update), only: %i(nodes)

View File

@@ -1,4 +1,4 @@
class Way < ActiveRecord::Base
class Way < ApplicationRecord
has_many :nodes, dependent: :destroy
def bbox=(bbox)

View File

@@ -4,7 +4,7 @@ xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
xml.channel do
xml.title "Recent maps at MapKnitter.org"
xml.link url_for :only_path => false, :controller => 'spectrums'
xml.link url_for only_path: false, controller: 'feeds', action: 'all'
xml.description "Recently posted maps at MapKnitter.org, a Public Lab open source research initiative"
@maps.each do |map|

View File

@@ -4,7 +4,7 @@ xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
xml.channel do
xml.title "Maps by "+params[:id]+" at MapKnitter.org"
xml.link url_for :only_path => false, :controller => 'spectrums'
xml.link url_for only_path: false, controller: 'feeds', action: 'author'
xml.description "Recently posted maps at MapKnitter.org, a Public Laboratory open source research initiative"
@maps.each do |map|

View File

@@ -4,7 +4,7 @@ xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
xml.channel do
xml.title "Recent maps at MapKnitter.org"
xml.link url_for :only_path => false, :controller => 'spectrums'
xml.link url_for only_path: false, controller: 'feeds', action: 'clean'
xml.description "Recently posted maps at MapKnitter.org, a Public Lab open source research initiative"
@maps.each do |map|

View File

@@ -4,7 +4,7 @@ xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
xml.channel do
xml.title "Recent maps at MapKnitter.org"
xml.link url_for :only_path => false, :controller => 'spectrums'
xml.link url_for only_path: false, controller: 'feeds', action: 'license'
xml.description "Recently posted maps at MapKnitter.org, a Public Laboratory open source research initiative"
@maps.each do |map|

View File

@@ -4,7 +4,7 @@ xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
xml.channel do
xml.title "Recent maps at MapKnitter.org"
xml.link url_for :only_path => false, :controller => 'spectrums'
xml.link url_for only_path: false, controller: 'feeds', action: 'tag'
xml.description "Recently posted maps at MapKnitter.org, a Public Laboratory open source research initiative"
@maps.each do |map|

View File

@@ -1,12 +1,8 @@
<%= stylesheet_link_tag "/lib/leaflet/dist/leaflet.css" %>
<%= stylesheet_link_tag "/lib/leaflet-environmental-layers/dist/LeafletEnvironmentalLayers.css" %>
<%= javascript_include_tag('/lib/leaflet-environmental-layers/dist/LeafletEnvironmentalLayers.js') %>
<%= javascript_include_tag('/lib/leaflet-environmental-layers/src/windRoseLayer.js') %>
<%= javascript_include_tag('https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/Leaflet.fullscreen.min.js') %>
<%= stylesheet_link_tag "https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/leaflet.fullscreen.css" %>
<%= javascript_include_tag('/lib/leaflet-spin/example/spin/dist/spin.min.js') %>
<%= javascript_include_tag('/lib/leaflet-spin/example/leaflet.spin.min.js') %>
<%= javascript_include_tag('/lib/leaflet-fullhash/leaflet-fullHash.js') %>
<%# <%= javascript_include_tag('https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/Leaflet.fullscreen.min.js') %>
<%# # <%= stylesheet_link_tag "https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/leaflet.fullscreen.css" %>
<%= javascript_include_tag('/assets/leaflet-spin/example/spin/dist/spin.min.js') %>
<%= javascript_include_tag('/assets/leaflet-spin/example/leaflet.spin.min.js') %>
<%= javascript_include_tag('leaflet-fullHash.js') %>
<style>
#hero {
@@ -251,7 +247,7 @@
defaultLoc.lng = defaultLoc.lng || <%= params[:lng] || 'false' %>;
defaultLoc.zoom = defaultLoc.zoom || <%= params[:z] || 'false' %>;
var Mapknitterunique = new L.Map('mapknitter-unique').setView([places[0].lat, places[0].lng], 8);
var Mapknitterunique = L.map('mapknitter-unique').setView([places[0].lat, places[0].lng], 8);
var hash = new L.Hash(Mapknitterunique);
var MapKnitter = L.layerGroup.mapKnitterLayer().addTo(Mapknitterunique);
@@ -301,7 +297,7 @@
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(Mapknitterunique);
Mapknitterunique.addControl(new L.Control.Fullscreen()); // to go full-screen
// Mapknitterunique.addControl(new L.Control.Fullscreen()); // to go full-screen
Mapknitterunique.on('fullscreenchange', function () {
if (Mapknitterunique.isFullscreen()) {
Mapknitterunique.options.minZoom = 3 ;

View File

@@ -20,7 +20,7 @@
</li>
<% end %>
<script>
$(function(){
$("#loginModal").appendTo("body");
});
jQuery(document).ready(function($) {
$("#loginModal").appendTo("body");
});
</script>

View File

@@ -9,19 +9,14 @@
<meta name="description" content="<%= @map.description.gsub('"',"'") if @map.description %>" />
<meta name="viewport" content="width=320, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<link rel="stylesheet" href="/lib/leaflet/dist/leaflet.css"/>
<link rel="shortcut icon" href="/images/mapknitter-255.png" />
<%= stylesheet_link_tag 'application' %>
<%= javascript_include_tag 'application' %>
<%= javascript_include_tag 'maps' %>
<%= javascript_include_tag 'uploads' %>
<% if @annotations %><%= javascript_include_tag 'annotations' %><% end %>
<script src='//api.tiles.mapbox.com/mapbox.js/plugins/leaflet-omnivore/v0.3.1/leaflet-omnivore.min.js' async defer></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAxlBXzYwdeaOMKZgx_UNBp2qBtdD0L_9g"></script>
<script src='https://unpkg.com/leaflet.gridlayer.googlemutant@0.7.0/Leaflet.GoogleMutant.js'></script>
<script src='/lib/image-sequencer/dist/image-sequencer.js'></script>
</head>
<body>

View File

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>/* Email styles need to be inline */</style>
</head>
<body><%= yield %></body>
</html>

View File

@@ -0,0 +1 @@
<%= yield %>

View File

@@ -30,7 +30,6 @@
</style>
<script src="/lib/leaflet/dist/leaflet.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" href="/lib/leaflet/dist/leaflet.css" type="text/css" media="screen" title="no title" charset="utf-8">
<script src="https://maps.google.com/maps/api/js?v=3.2&sensor=false"></script>
<script src="/lib/leaflet-google/index.js"></script>

View File

@@ -6,7 +6,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="/lib/leaflet/dist/leaflet.js"></script>
<link href="/lib/leaflet/dist/leaflet.css" rel="stylesheet"/>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/leaflet-distortableimage/lib/easybutton.js"></script>
<link rel="stylesheet" href="/lib/leaflet-distortableimage/DistortableImageOverlay.css"/>
@@ -83,8 +82,8 @@
});
img.mk_id = <%= warpable.id %>
img.onDeselect = function() {
$.ajax('/images/update',{
type: 'POST',
$.ajax('/images',{
type: 'PATCH',
data: {
warpable_id: this.mk_id,
locked: this.locked,

View File

@@ -1,9 +1,5 @@
<%= javascript_include_tag('/lib/leaflet-fullhash/leaflet-fullHash.js') %>
<%= javascript_include_tag('https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/Leaflet.fullscreen.min.js') %>
<%= stylesheet_link_tag "https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/leaflet.fullscreen.css" %>
<%= javascript_include_tag('/lib/leaflet-spin/example/spin/dist/spin.min.js') %>
<%= javascript_include_tag('/lib/leaflet-spin/example/leaflet.spin.min.js') %>
<%= javascript_include_tag('/assets/leaflet-spin/example/spin/dist/spin.min.js') %>
<%= javascript_include_tag('/assets/leaflet-spin/example/leaflet.spin.min.js') %>
<div class="container-fluid">
<div id="mapknitter-unique" style="height: 300px ; width: 100% ; margin-bottom: 1%; z-index: 5;"></div>
@@ -120,122 +116,123 @@
</div>
<script>
$(function(){
jQuery(document).ready(function($) {
$("#loginModal").appendTo("body");
});
var bounds = L.latLngBounds(L.latLng(84.67351257 , -172.96875) , L.latLng(-54.36775852 , 178.59375)) ;
var Mapknitterunique = L.map('mapknitter-unique' , {
maxBounds: bounds ,
maxBoundsViscosity: 0.75
}).setView([43, -83] , 2);
Mapknitterunique.options.minZoom = 2 ;
//L.tileLayer('').addTo() ;
// L.layerGroup.mapKnitterLayer().addTo(Mapknitterunique);
var baselayer = L.tileLayer('https://a.tiles.mapbox.com/v3/jywarren.map-lmrwb2em/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(Mapknitterunique) ;
var bounds = new L.LatLngBounds(new L.LatLng(84.67351257 , -172.96875) , new L.LatLng(-54.36775852 , 178.59375)) ;
var Mapknitterunique = new L.map('mapknitter-unique' , {
maxBounds: bounds ,
maxBoundsViscosity: 0.75
}).setView([43, -83] , 2);
Mapknitterunique.options.minZoom = 2 ;
Mapknitterunique.addControl(new L.Control.Fullscreen()); // to go full-screen
Mapknitterunique.on('fullscreenchange', function () {
if (Mapknitterunique.isFullscreen()) {
Mapknitterunique.options.minZoom = 3 ;
}
else {
Mapknitterunique.options.minZoom = 1 ;
// Mapknitterunique.panTo(new L.LatLng(lat,lon));
//L.tileLayer('').addTo() ;
// L.layerGroup.mapKnitterLayer().addTo(Mapknitterunique);
var baselayer = L.tileLayer('https://a.tiles.mapbox.com/v3/jywarren.map-lmrwb2em/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(Mapknitterunique) ;
Mapknitterunique.addControl(new L.Control.Fullscreen()); // to go full-screen
Mapknitterunique.on('fullscreenchange', function () {
if (Mapknitterunique.isFullscreen()) {
Mapknitterunique.options.minZoom = 3 ;
}
});
else {
Mapknitterunique.options.minZoom = 1 ;
// Mapknitterunique.panTo(new L.LatLng(lat,lon));
}
});
// var PurpleLayer = L.layerGroup.purpleLayer() ;
var PurpleAirMarkerLayer = L.layerGroup.purpleAirMarkerLayer() ;
var SkyTruth = L.layerGroup.skyTruthLayer() ;
var Fractracker = L.layerGroup.fracTrackerLayer() ;
var OdorReport = L.layerGroup.odorReportLayer() ;
var MapKnitter = L.layerGroup.mapKnitterLayer().addTo(Mapknitterunique) ;
var ToxicRelease = L.layerGroup.toxicReleaseLayer() ;
// var PurpleLayer = L.layerGroup.purpleLayer() ;
var PurpleAirMarkerLayer = L.layerGroup.purpleAirMarkerLayer() ;
var SkyTruth = L.layerGroup.skyTruthLayer() ;
var Fractracker = L.layerGroup.fracTrackerLayer() ;
var OdorReport = L.layerGroup.odorReportLayer() ;
var MapKnitter = L.layerGroup.mapKnitterLayer().addTo(Mapknitterunique) ;
var ToxicRelease = L.layerGroup.toxicReleaseLayer() ;
var OpenInfraMap_Power = L.tileLayer('https://tiles-{s}.openinframap.org/power/{z}/{x}/{y}.png',{
maxZoom: 18,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://www.openinframap.org/about.html">About OpenInfraMap</a>'
});
var OpenInfraMap_Petroleum = L.tileLayer('https://tiles-{s}.openinframap.org/petroleum/{z}/{x}/{y}.png', {
var OpenInfraMap_Power = L.tileLayer('https://tiles-{s}.openinframap.org/power/{z}/{x}/{y}.png',{
maxZoom: 18,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://www.openinframap.org/about.html">About OpenInfraMap</a>'
});
var OpenInfraMap_Telecom = L.tileLayer('https://tiles-{s}.openinframap.org/telecoms/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://www.openinframap.org/about.html">About OpenInfraMap</a>'
});
var OpenInfraMap_Water = L.tileLayer('https://tiles-{s}.openinframap.org/water/{z}/{x}/{y}.png',{
maxZoom: 18,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://www.openinframap.org/about.html">About OpenInfraMap</a>'
});
});
var OpenInfraMap_Petroleum = L.tileLayer('https://tiles-{s}.openinframap.org/petroleum/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://www.openinframap.org/about.html">About OpenInfraMap</a>'
});
var OpenInfraMap_Telecom = L.tileLayer('https://tiles-{s}.openinframap.org/telecoms/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://www.openinframap.org/about.html">About OpenInfraMap</a>'
});
var OpenInfraMap_Water = L.tileLayer('https://tiles-{s}.openinframap.org/water/{z}/{x}/{y}.png',{
maxZoom: 18,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://www.openinframap.org/about.html">About OpenInfraMap</a>'
});
var Justicemap_income = L.tileLayer.provider('JusticeMap.income') ;
var JusticeMap_americanIndian = L.tileLayer.provider('JusticeMap.americanIndian') ;
var JusticeMap_asian = L.tileLayer.provider('JusticeMap.asian') ;
var JusticeMap_black = L.tileLayer.provider('JusticeMap.black') ;
var JusticeMap_multi = L.tileLayer.provider('JusticeMap.multi') ;
var JusticeMap_hispanic = L.tileLayer.provider('JusticeMap.hispanic') ;
var JusticeMap_nonWhite = L.tileLayer.provider('JusticeMap.nonWhite') ;
var JusticeMap_white = L.tileLayer.provider('JusticeMap.white') ;
var JusticeMap_plurality = L.tileLayer.provider('JusticeMap.plurality') ;
var Justicemap_income = L.tileLayer.provider('JusticeMap.income') ;
var JusticeMap_americanIndian = L.tileLayer.provider('JusticeMap.americanIndian') ;
var JusticeMap_asian = L.tileLayer.provider('JusticeMap.asian') ;
var JusticeMap_black = L.tileLayer.provider('JusticeMap.black') ;
var JusticeMap_multi = L.tileLayer.provider('JusticeMap.multi') ;
var JusticeMap_hispanic = L.tileLayer.provider('JusticeMap.hispanic') ;
var JusticeMap_nonWhite = L.tileLayer.provider('JusticeMap.nonWhite') ;
var JusticeMap_white = L.tileLayer.provider('JusticeMap.white') ;
var JusticeMap_plurality = L.tileLayer.provider('JusticeMap.plurality') ;
var clouds = L.OWM.clouds({showLegend: true, opacity: 0.5});
var cloudscls = L.OWM.cloudsClassic({});
var precipitation = L.OWM.precipitation({});
var precipitationcls = L.OWM.precipitationClassic({});
var rain = L.OWM.rain({});
var raincls = L.OWM.rainClassic({});
var snow = L.OWM.snow({});
var pressure = L.OWM.pressure({});
var pressurecntr = L.OWM.pressureContour({});
var temp = L.OWM.temperature({});
var wind = L.OWM.wind({});
var clouds = L.OWM.clouds({showLegend: true, opacity: 0.5});
var cloudscls = L.OWM.cloudsClassic({});
var precipitation = L.OWM.precipitation({});
var precipitationcls = L.OWM.precipitationClassic({});
var rain = L.OWM.rain({});
var raincls = L.OWM.rainClassic({});
var snow = L.OWM.snow({});
var pressure = L.OWM.pressure({});
var pressurecntr = L.OWM.pressureContour({});
var temp = L.OWM.temperature({});
var wind = L.OWM.wind({});
var city = L.OWM.current({intervall: 15, minZoom: 3});
var windrose = L.OWM.current({intervall: 15, minZoom: 3, markerFunction: myWindroseMarker, popup: false, clusterSize: 50,imageLoadingBgUrl: 'https://openweathermap.org/img/w0/iwind.png' });
windrose.on('owmlayeradd', windroseAdded, windrose);
var city = L.OWM.current({intervall: 15, minZoom: 3});
var windrose = L.OWM.current({intervall: 15, minZoom: 3, markerFunction: myWindroseMarker, popup: false, clusterSize: 50,imageLoadingBgUrl: 'https://openweathermap.org/img/w0/iwind.png' });
windrose.on('owmlayeradd', windroseAdded, windrose);
var baseMaps = {
"Baselayer1": baselayer
};
var overlayMaps = {
// "PurpleAirLayer-HeatMap": PurpleLayer ,
"PurpleAirLayer-Markers": PurpleAirMarkerLayer ,
"SkyTruth": SkyTruth ,
"Fractracker" : Fractracker ,
"ToxicRelease": ToxicRelease ,
"OdorReport": OdorReport ,
"MapKnitter": MapKnitter ,
"OpenInfraMap_Power": OpenInfraMap_Power ,
"OpenInfraMap_Telecom": OpenInfraMap_Telecom ,
"OpenInfraMap_Petroleum": OpenInfraMap_Petroleum ,
"OpenInfraMap_Water": OpenInfraMap_Water ,
"Justicemap_income": Justicemap_income,
"JusticeMap_americanIndian": JusticeMap_americanIndian ,
"JusticeMap_asian": JusticeMap_asian ,
"JusticeMap_black": JusticeMap_black,
"JusticeMap_multi": JusticeMap_multi ,
"JusticeMap_hispanic": JusticeMap_hispanic ,
"JusticeMap_nonWhite": JusticeMap_nonWhite,
"JusticeMap_white": JusticeMap_white ,
"JusticeMap_plurality": JusticeMap_plurality ,
"Clouds": clouds ,
"clouds (classic)": cloudscls ,
"precipitation": precipitation ,
"precipitation (classic)": precipitationcls ,
"rain": rain ,
"rain (classic)": raincls ,
"snow": snow ,
"pressure": pressure ,
"pressure contour (zoom in)": pressurecntr ,
"temp": temp ,
"wind": wind ,
"Cities (zoom in)": city ,
"windrose (zoom in)": windrose
};
L.control.layers(baseMaps,overlayMaps).addTo(Mapknitterunique);
var baseMaps = {
"Baselayer1": baselayer
};
var overlayMaps = {
// "PurpleAirLayer-HeatMap": PurpleLayer ,
"PurpleAirLayer-Markers": PurpleAirMarkerLayer ,
"SkyTruth": SkyTruth ,
"Fractracker" : Fractracker ,
"ToxicRelease": ToxicRelease ,
"OdorReport": OdorReport ,
"MapKnitter": MapKnitter ,
"OpenInfraMap_Power": OpenInfraMap_Power ,
"OpenInfraMap_Telecom": OpenInfraMap_Telecom ,
"OpenInfraMap_Petroleum": OpenInfraMap_Petroleum ,
"OpenInfraMap_Water": OpenInfraMap_Water ,
"Justicemap_income": Justicemap_income,
"JusticeMap_americanIndian": JusticeMap_americanIndian ,
"JusticeMap_asian": JusticeMap_asian ,
"JusticeMap_black": JusticeMap_black,
"JusticeMap_multi": JusticeMap_multi ,
"JusticeMap_hispanic": JusticeMap_hispanic ,
"JusticeMap_nonWhite": JusticeMap_nonWhite,
"JusticeMap_white": JusticeMap_white ,
"JusticeMap_plurality": JusticeMap_plurality ,
"Clouds": clouds ,
"clouds (classic)": cloudscls ,
"precipitation": precipitation ,
"precipitation (classic)": precipitationcls ,
"rain": rain ,
"rain (classic)": raincls ,
"snow": snow ,
"pressure": pressure ,
"pressure contour (zoom in)": pressurecntr ,
"temp": temp ,
"wind": wind ,
"Cities (zoom in)": city ,
"windrose (zoom in)": windrose
};
L.control.layers(baseMaps,overlayMaps).addTo(Mapknitterunique);
</script>

View File

@@ -1,13 +1,12 @@
<%= stylesheet_link_tag "/lib/leaflet/dist/leaflet.css" %>
<%= stylesheet_link_tag "/lib/leaflet-environmental-layers/dist/LeafletEnvironmentalLayers.css" %>
<%= javascript_include_tag('/lib/leaflet-environmental-layers/dist/LeafletEnvironmentalLayers.js') %>
<%= javascript_include_tag('/lib/leaflet-environmental-layers/dist/windRoseLayer.js') %>
<%= javascript_include_tag('/lib/leaflet-fullhash/leaflet-fullHash.js') %>
<%= stylesheet_link_tag "/assets/leaflet-environmental-layers/dist/LeafletEnvironmentalLayers.css" %>
<%= javascript_include_tag('/assets/leaflet-environmental-layers/dist/LeafletEnvironmentalLayers.js') %>
<%= javascript_include_tag('/assets/leaflet-environmental-layers/dist/windRoseLayer.js') %>
<%= javascript_include_tag('/assets/leaflet-fullhash/leaflet-fullHash.js') %>
<%= javascript_include_tag('https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/Leaflet.fullscreen.min.js') %>
<%= stylesheet_link_tag "https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/leaflet.fullscreen.css" %>
<%= javascript_include_tag('/lib/leaflet-spin/example/spin/dist/spin.min.js') %>
<%= javascript_include_tag('/lib/leaflet-spin/example/leaflet.spin.min.js') %>
<%= javascript_include_tag('/assets/leaflet-spin/example/spin/dist/spin.min.js') %>
<%= javascript_include_tag('/assets/leaflet-spin/example/leaflet.spin.min.js') %>
<div class="container-fluid">
<div id="mapknitter-unique" class="mx-auto" style="height: 450px; width: 100%;">

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
load Gem.bin_path('bundler', 'bundle')

View File

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

View File

@@ -1,29 +1,36 @@
#!/usr/bin/env ruby
require 'pathname'
require 'fileutils'
include FileUtils
# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir APP_ROOT do
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
chdir APP_ROOT do
# This script is a starting point to setup your application.
# Add necessary setup steps to this file:
# Add necessary setup steps to this file.
puts "== Installing dependencies =="
system "gem install bundler --conservative"
system "bundle check || bundle install"
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
# Install JavaScript dependencies if using Yarn
# system('bin/yarn')
# puts "\n== Copying sample files =="
# unless File.exist?("config/database.yml")
# system "cp config/database.yml.sample config/database.yml"
# unless File.exist?('config/database.yml')
# cp 'config/database.yml.sample', 'config/database.yml'
# end
puts "\n== Preparing database =="
system "bin/rake db:setup"
system! 'bin/rails db:setup'
puts "\n== Removing old logs and tempfiles =="
system "rm -f log/*"
system "rm -rf tmp/cache"
system! 'bin/rails log:clear tmp:clear'
puts "\n== Restarting application server =="
system "touch tmp/restart.txt"
system! 'bin/rails restart'
end

31
bin/update Executable file
View File

@@ -0,0 +1,31 @@
#!/usr/bin/env ruby
require 'fileutils'
include FileUtils
# path to your application root.
APP_ROOT = File.expand_path('..', __dir__)
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
chdir APP_ROOT do
# This script is a way to update your development environment automatically.
# Add necessary update steps to this file.
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
# Install JavaScript dependencies if using Yarn
# system('bin/yarn')
puts "\n== Updating database =="
system! 'bin/rails db:migrate'
puts "\n== Removing old logs and tempfiles =="
system! 'bin/rails log:clear tmp:clear'
puts "\n== Restarting application server =="
system! 'bin/rails restart'
end

11
bin/yarn Executable file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/env ruby
APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir(APP_ROOT) do
begin
exec "yarnpkg", *ARGV
rescue Errno::ENOENT
$stderr.puts "Yarn executable was not detected in the system."
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
exit 1
end
end

View File

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

View File

@@ -1,5 +1,4 @@
require File.expand_path('../boot', __FILE__)
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
@@ -27,6 +26,9 @@ module Mapknitter
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
@@ -39,16 +41,12 @@ module Mapknitter
# parameters by using an attr_accessible or attr_protected declaration.
# config.active_record.whitelist_attributes = true
# Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true
# Enable the asset pipeline
config.assets.enabled = true
config.action_dispatch.default_headers['X-Frame-Options'] = "ALLOW-FROM https://publiclab.org"
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.3'
config.assets.paths << Rails.root.join("public","lib")
end
end

View File

@@ -1,3 +1,4 @@
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) # Set up gems listed in the Gemfile.
require 'bundler/setup' # Set up gems listed in the Gemfile.
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.

10
config/cable.yml Normal file
View File

@@ -0,0 +1,10 @@
development:
adapter: async
test:
adapter: async
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: mapknitter_production

View File

@@ -14,7 +14,7 @@ production:
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: db
host: <%= ENV.fetch("MYSQL_HOST") { '127.0.0.1' } %>
username: mapknitter
password: mapknitter
database: mapknitter

View File

@@ -1,5 +1,5 @@
# Load the Rails application.
require File.expand_path('../application', __FILE__)
require_relative 'application'
# Initialize the Rails application.
Mapknitter::Application.initialize!
Rails.application.initialize!

View File

@@ -1,4 +1,4 @@
Mapknitter::Application.configure do
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded on
@@ -9,13 +9,41 @@ Mapknitter::Application.configure do
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Show full error reports.
config.consider_all_requests_local = true
# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
if Rails.root.join('tmp', 'caching-dev.txt').exist?
config.action_controller.perform_caching = true
config.cache_store = :memory_store
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{2.days.to_i}"
}
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
# Store uploaded files on the local file system (see config/storage.yml for options)
config.active_storage.service = :local
config.action_mailer.perform_caching = false
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
# yet still be able to expire them through the digest params.
config.assets.digest = true
# Adds additional error checking when serving assets at runtime.
# Checks for improperly declared sprockets dependencies.
# Raises helpful error messages.
config.assets.raise_runtime_errors = true
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
@@ -26,25 +54,24 @@ Mapknitter::Application.configure do
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true
# Do not compress assets
config.assets.compress = false
# Expands the lines which load the assets
config.assets.logger = false
config.assets.debug = true#false
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
# yet still be able to expire them through the digest params.
config.assets.digest = true
config.serve_static_files = true
# Adds additional error checking when serving assets at runtime.
# Checks for improperly declared sprockets dependencies.
# Raises helpful error messages.
config.assets.raise_runtime_errors = true
# Suppress logger output for asset requests.
config.assets.quiet = true
# Highlight code that triggered database queries in logs.
config.active_record.verbose_query_logs = true
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
# Do not compress assets
config.assets.compress = false
# Expands the lines which load the assets
config.assets.debug = true#false
config.serve_static_files = true
config.assets.logger = false
# Use an evented file watcher to asynchronously detect changes in source code,
# routes, locales, etc. This feature depends on the listen gem.
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
end

View File

@@ -1,5 +1,6 @@
Mapknitter::Application.configure do
require 'uglifier'
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
@@ -15,15 +16,13 @@ Mapknitter::Application.configure do
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Enable Rack::Cache to put a simple HTTP cache in front of your application
# Add `rack-cache` to your Gemfile before enabling this.
# For large-scale production use, consider using a caching reverse proxy like
# NGINX, varnish or squid.
# config.action_dispatch.rack_cache = true
# Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
# or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
# config.require_master_key = true
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
# Compress JavaScripts and CSS.
require 'uglifier'
@@ -37,18 +36,23 @@ Mapknitter::Application.configure do
# yet still be able to expire them through the digest params.
config.assets.digest = true
config.assets.precompile << /\.(?:svg|eot|woff|ttf)\z/
config.assets.precompile += ['tags.js',
'uploads.js',
'knitter.js',
'annotations.js',
'maps.js']
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'
# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Store uploaded files on the local file system (see config/storage.yml for options)
config.active_storage.service = :local
# Mount Action Cable outside main process or domain
# config.action_cable.mount_path = nil
# config.action_cable.url = 'wss://example.com/cable'
# config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
@@ -57,25 +61,20 @@ Mapknitter::Application.configure do
config.log_level = :debug
# Prepend all log lines with the following tags.
# config.log_tags = [ :subdomain, :uuid ]
# Use a different logger for distributed setups.
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
config.log_tags = [ :request_id ]
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'
# Use a real queuing backend for Active Job (and separate queues per environment)
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "mapknitter_#{Rails.env}"
config.action_mailer.perform_caching = false
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
config.action_mailer.delivery_method = :sendmail
config.action_mailer.sendmail_settings = {
location: '/usr/sbin/sendmail',
arguments: '-i'
}
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
@@ -87,6 +86,21 @@ Mapknitter::Application.configure do
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
config.action_mailer.delivery_method = :sendmail
config.action_mailer.sendmail_settings = {
location: '/usr/sbin/sendmail',
arguments: '-i'
}
# Use a different logger for distributed setups.
# require 'syslog/logger'
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
end

View File

@@ -1,5 +1,4 @@
Mapknitter::Application.configure do
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# The test environment is used exclusively to run your application's
@@ -13,9 +12,11 @@ Mapknitter::Application.configure do
# preloads Rails for running tests, you may have to set it to true.
config.eager_load = false
# Configure static file server for tests with Cache-Control for performance.
config.serve_static_files = true
config.static_cache_control = 'public, max-age=3600'
# Configure public file server for tests with Cache-Control for performance.
config.public_file_server.enabled = true
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{1.hour.to_i}"
}
# Show full error reports and disable caching.
config.consider_all_requests_local = true
@@ -27,14 +28,16 @@ Mapknitter::Application.configure do
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false
# Store uploaded files on the local file system in a temporary directory
config.active_storage.service = :test
config.action_mailer.perform_caching = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Randomize the order test cases are executed.
config.active_support.test_order = :random
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
config.after_initialize do

View File

@@ -0,0 +1 @@
Rails.application.config.active_record.belongs_to_required_by_default = true

View File

@@ -0,0 +1,8 @@
# Be sure to restart your server when you modify this file.
# ActiveSupport::Reloader.to_prepare do
# ApplicationController.renderer.defaults.merge!(
# http_host: 'example.org',
# https: false
# )
# end

View File

@@ -1,17 +1,26 @@
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'
Rails.application.config.assets.precompile += %w[*.png *.jpg *.jpeg *.gif *.svg]
Rails.application.configure do
# Version of your assets, change this if you want to expire all your assets.
config.assets.version = '1.3'
config.assets.precompile += %w[*.png *.jpg *.jpeg *.gif]
# Add additional assets to the asset load path
# Rails.application.config.assets.paths << Emoji.images_path
# Add additional assets to the asset load path.
# Rails.application.config.assets.paths << Emoji.images_path
# Add Yarn node_modules folder to the asset load path.
config.assets.paths << Rails.root.join('node_modules')
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# Rails.application.config.assets.precompile += %w( search.js )
Rails.application.config.assets.precompile += ['tags.js',
'uploads.js',
'knitter.js',
'annotations.js',
'maps.js']
config.assets.precompile << /\.(?:svg|eot|woff|ttf)\z/
config.assets.precompile += ['uploads.js',
'knitter.js',
'annotations.js',
'maps.js',
'mapknitter.js',
'leaflet-fullHash.js'
]
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
end

View File

@@ -11,15 +11,15 @@
# or, alternatively,
# This can also be removed if DEFAULT NULL is removed from all columns;
# Read more at https://github.com/publiclab/mapknitter/pull/323
# # This can also be removed if DEFAULT NULL is removed from all columns;
# # Read more at https://github.com/publiclab/mapknitter/pull/323
class ActiveRecord::ConnectionAdapters::ColumnDefinition
if ActiveRecord::Base.connection.adapter_name != 'sqlite3' && ActiveRecord::Base.connection.adapter_name != 'SQLite'
def sql_type
type.to_sym == :primary_key ? 'int(11) auto_increment PRIMARY KEY' : base.type_to_sql(type.to_sym, limit, precision, scale) rescue type
end
end
# if ActiveRecord::Base.connection.adapter_name != 'sqlite3' && ActiveRecord::Base.connection.adapter_name != 'SQLite'
# def sql_type
# type.to_sym == :primary_key ? 'int(11) auto_increment PRIMARY KEY' : base.type_to_sql(type.to_sym, limit, precision, scale) rescue type
# end
# end
end

View File

@@ -0,0 +1,25 @@
# Be sure to restart your server when you modify this file.
# Define an application-wide content security policy
# For further information see the following documentation
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
# Rails.application.config.content_security_policy do |policy|
# policy.default_src :self, :https
# policy.font_src :self, :https, :data
# policy.img_src :self, :https, :data
# policy.object_src :none
# policy.script_src :self, :https
# policy.style_src :self, :https
# # Specify URI for violation reports
# # policy.report_uri "/csp-violation-report-endpoint"
# end
# If you are using UJS then enable automatic nonce generation
# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
# Report CSP violations to a specified URI
# For further information see the following documentation:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
# Rails.application.config.content_security_policy_report_only = true

View File

@@ -1,3 +1,5 @@
# Be sure to restart your server when you modify this file.
# Specify a serializer for the signed and encrypted cookie jars.
# Valid options are :json, :marshal, and :hybrid.
Rails.application.config.action_dispatch.cookies_serializer = :hybrid

View File

@@ -1,48 +0,0 @@
# this is a customization created to bridge incompatabilities when upgrading Ruby 2.1.2
# to 2.4.4 with Rails 3.2.
# explanation
# There's a fundamental asymmetry in how operators work in Ruby -
# `1 * 1.second` dispatches -> * on Integer.
# `1.second * 1` dispatches -> * on Duration -> throws error 'Duration can't be coerced into Integer'
# the source code for Rails 3.2 puts duration second: https://github.com/rails/rails/blob/v3.2.22.5/activesupport/lib/active_support/core_ext/numeric/time.rb
# the solution: the order of multiplication has to be swtiched, and Duration put first.
# this code can be removed with ActiveSupport v.5.0.3: https://github.com/rails/rails/blob/v5.0.3/activesupport/lib/active_support/core_ext/numeric/time.rb
# (Rails 5)
class Numeric
def days
ActiveSupport::Duration.new(24.hours * self, [[:days, self]])
end
alias :day :days
def weeks
ActiveSupport::Duration.new(7.days * self, [[:days, self * 7]])
end
alias :week :weeks
def fortnights
ActiveSupport::Duration.new(2.weeks * self, [[:days, self * 14]])
end
alias :fortnight :fortnights
end
# source code: https://github.com/rails/rails/blob/v3.2.22.5/activesupport/lib/active_support/core_ext/integer/time.rb
# fixed as of ActiveSupport v.4.1.2 https://github.com/rails/rails/blob/v4.1.12/activesupport/lib/active_support/core_ext/integer/time.rb
# (Rails 4)
class Integer
def months
ActiveSupport::Duration.new(30.days * self, [[:months, self]])
end
alias :month :months
def years
ActiveSupport::Duration.new(365.25.days * self, [[:years, self]])
end
alias :year :years
end

View File

@@ -0,0 +1,38 @@
# Be sure to restart your server when you modify this file.
#
# This file contains migration options to ease your Rails 5.2 upgrade.
#
# Once upgraded flip defaults one by one to migrate to the new default.
#
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
# Make Active Record use stable #cache_key alongside new #cache_version method.
# This is needed for recyclable cache keys.
# Rails.application.config.active_record.cache_versioning = true
# Use AES-256-GCM authenticated encryption for encrypted cookies.
# Also, embed cookie expiry in signed or encrypted cookies for increased security.
#
# This option is not backwards compatible with earlier Rails versions.
# It's best enabled when your entire app is migrated and stable on 5.2.
#
# Existing cookies will be converted on read then written with the new scheme.
# Rails.application.config.action_dispatch.use_authenticated_cookie_encryption = true
# Use AES-256-GCM authenticated encryption as default cipher for encrypting messages
# instead of AES-256-CBC, when use_authenticated_message_encryption is set to true.
# Rails.application.config.active_support.use_authenticated_message_encryption = true
# Add default protection from forgery to ActionController::Base instead of in
# ApplicationController.
# Rails.application.config.action_controller.default_protect_from_forgery = true
# Store boolean values are in sqlite3 databases as 1 and 0 instead of 't' and
# 'f' after migrating old data.
# Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
# Use SHA-1 instead of MD5 to generate non-sensitive digests, such as the ETag header.
# Rails.application.config.active_support.use_sha1_digests = true
# Make `form_with` generate id attributes for any generated HTML tags.
# Rails.application.config.action_view.form_with_generates_ids = true

View File

@@ -1,7 +1,8 @@
require "recaptcha/rails"
class ActionView::Base
include Recaptcha::ClientHelper
include Recaptcha::Adapters::ViewMethods
include Recaptcha::Adapters::ControllerMethods
end
Recaptcha.configure do |config|

View File

@@ -4,4 +4,4 @@
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Mapknitter::Application.config.secret_token = 'asdfjdasgaisaolghrwiohrkahguilboiwelkxwbranjkl'
Mapknitter::Application.config.secret_key_base = 'asdfjdasgaisaolghrwiohrkahguilboiwelkxwbranjkl'

View File

@@ -5,10 +5,10 @@
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
wrap_parameters format: [:json]
end
# Disable root element in JSON for ActiveRecord objects.
# To enable root element in JSON for ActiveRecord objects.
# ActiveSupport.on_load(:active_record) do
# self.include_root_in_json = false
# self.include_root_in_json = true
# end

View File

@@ -16,6 +16,16 @@
#
# This would use the information in config/locales/es.yml.
#
# The following keys must be escaped otherwise they will not be retrieved by
# the default I18n backend:
#
# true, false, on, off, yes, no
#
# Instead, surround them with single quotes.
#
# en:
# 'true': 'foo'
#
# To learn more, please read the Rails Internationalization guide
# available at http://guides.rubyonrails.org/i18n.html.

View File

@@ -1,72 +1,92 @@
Mapknitter::Application.routes.draw do
root :to => 'front_ui#index'
root to: 'front_ui#index'
get 'legacy' => 'maps#index' # remove once new front page is stable
get 'front-page' => 'front_ui#index'
get 'mappers' => 'front_ui#nearby_mappers'
get 'gallery' => 'front_ui#gallery'
post "save_location" => 'front_ui#save_location'
get 'about' => 'front_ui#about'
get 'all_maps' => 'front_ui#all_maps'
get 'anonymous' => 'front_ui#anonymous'
get 'front-page', to: 'front_ui#index'
get 'mappers', to: 'front_ui#nearby_mappers'
get 'about', to: 'front_ui#about'
get 'all_maps', to: 'front_ui#all_maps'
get 'anonymous', to: 'front_ui#anonymous'
get 'gallery', to: 'front_ui#gallery'
post 'save_location', to: 'front_ui#save_location'
get 'external_url_test' => 'export#external_url_test'
get 'local/:login' => 'sessions#local'
get 'logout' => 'sessions#logout'
get 'login' => 'sessions#new'
get 'register' => 'users#create'
get 'signup' => 'users#new'
get 'legacy', to: 'maps#index' # remove once new front page is stable
get 'external_url_test', to: 'export#external_url_test'
# since rails 3.2, we use this to log in:
get 'sessions/create' => 'sessions#create'
get 'sessions/create', to: 'sessions#create'
get 'local/:login', to: 'sessions#local'
get 'logout', to: 'sessions#logout'
get 'login', to: 'sessions#new'
resources :users, :sessions, :maps
resources :users, :sessions, :maps, :images, :comments, :tags
# redirect legacy route:
get 'tag/:id', to: redirect('/tags/%{id}')
get 'tags/:id' => 'tags#show'
# Registered user pages:
get 'profile' => 'users#profile', :id => 0
get 'profile/:id' => 'users#profile'
get 'dashboard' => 'users#dashboard'
get 'register', to: 'users#create'
get 'signup', to: 'users#new'
get 'profile', to: 'users#profile', id: 0
get 'profile/:id', to: 'users#profile'
get 'dashboard', to: 'users#dashboard'
get 'authors', to: 'users#index'
get 'authors' => 'users#index'
get 'images/:url', to: 'images#fetch'
get 'feeds/all' => 'feeds#all', :format => 'rss'
get 'feeds/license/:id' => 'feeds#license', :format => 'rss'
get 'feeds/author/:id' => 'feeds#author', :format => 'rss'
get 'feeds/tag/:id' => 'feeds#tag', :format => 'rss'
get 'tms/:id/alt/:z/:x/:y.png' => 'utility#tms_alt'
get 'tms/:id/' => 'utility#tms_info'
get 'tms/:id/alt/' => 'utility#tms_info'
get 'tms/:id/alt/:z/:x/:y.png', to: 'utility#tms_alt'
get 'tms/:id/', to: 'utility#tms_info'
get 'tms/:id/alt/', to: 'utility#tms_info'
# once we have string-based ids, reorganize these around 'maps' and resourceful routing
get 'map/map' => 'maps#map'
get 'search/:id' => 'maps#search'
get 'search' => 'maps#search'
get 'map/archive/:id' => 'maps#archive'
get 'map/region/:id' => 'maps#region'
get 'map/license/:id' => 'maps#license'
get 'maps/featured' => 'maps#featured'
get 'map/view/:id', to: redirect('/maps/%{id}') # legacy
get 'maps/:id/annotate' => 'maps#annotate'
get 'maps/exports/:id' => 'maps#exports'
get 'maps/:id/warpables' => 'maps#images' # deprecate this in favor of resourceful route below; this is just to override maps/:id
post 'maps/:map_id/warpables' => 'images#create' # deprecate this in favor of resourceful route below; this is just to override maps/:id
get 'export/progress/:id' => 'export#progress'
get 'export/status/:id' => 'export#status'
get 'search/:id', to: 'maps#search'
get 'search', to: 'maps#search'
get 'maps/:id/warpables', to: 'maps#images' # deprecate this in favor of resourceful route below; this is just to override maps/:id
get 'maps/view/:id', to: redirect('/maps/%{id}') # legacy
get 'export/progress/:id', to: 'export#progress'
get 'export/status/:id', to: 'export#status'
get 'exports', to: 'export#index'
post 'export' => 'export#create'
get 'exports' => 'export#index'
get 'map/:id', to: redirect('/maps/%{id}')
get 'embed/:id' => 'maps#embed'
post 'maps/export/:id' => 'maps#export'
post 'maps/:id' => 'maps#export'
get 'embed/:id', to: 'maps#embed'
post 'maps/:map_id/warpables', to: 'images#create' # deprecate this in favor of resourceful route below; this is just to override maps/:id
post 'maps/export/:id', to: 'maps#export'
post 'maps/:id', to: 'maps#export'
get 'import/:name' => 'images#import' # this was for auto-adding images via URL
post 'export/:action/:id' => 'export'
get 'import/:name', to: 'images#import' # this was for auto-adding images via URL
namespace 'feeds' do
%w(all clean).each do |action|
get action, action: action, format: 'rss'
end
%w(license author tag).each do |action|
get action + "/:id", action: action, format: 'rss'
end
end
namespace 'maps' do
%w(map featured region license).each do |action|
get action, action: action
end
%w(archive exports region license).each do |action|
get action + "/:id", action: action
end
%w(annotate warpables).each do |action|
get "/:id/" + action, action: action
end
end
namespace 'export' do
%w(index logger jpg geotiff cancel
progress status external_url_test).each do |action|
post action + "/:id", action: action
end
end
# make these resourceful after renaming warpables to images
post 'images/create/:id' => 'images#create' # used?
@@ -88,13 +108,6 @@ Mapknitter::Application.routes.draw do
end
end
# See how all your routes lay out with 'rake routes'
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
get ':controller/:action'
get ':controller/:action/:id'
get ':controller/:action.:format'
get ':controller/:action/:id.:format'
# See how all your routes lay out with 'rails routes'
end

6
config/spring.rb Normal file
View File

@@ -0,0 +1,6 @@
%w[
.ruby-version
.rbenv-vars
tmp/restart.txt
tmp/caching-dev.txt
].each { |path| Spring.watch(path) }

34
config/storage.yml Normal file
View File

@@ -0,0 +1,34 @@
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>
# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
# amazon:
# service: S3
# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
# region: us-east-1
# bucket: your_own_bucket
# Remember not to checkin your GCS keyfile to a repository
# google:
# service: GCS
# project: your_project
# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
# bucket: your_own_bucket
# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
# microsoft:
# service: AzureStorage
# storage_account_name: your_account_name
# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
# container: your_container_name
# mirror:
# service: Mirror
# primary: local
# mirrors: [ amazon, google, microsoft ]

View File

@@ -1,4 +1,4 @@
class CreateTweets < ActiveRecord::Migration
class CreateTweets < ActiveRecord::Migration[5.2]
def self.up
create_table :tweets do |t|

View File

@@ -1,4 +1,4 @@
class CreateMessages < ActiveRecord::Migration
class CreateMessages < ActiveRecord::Migration[5.2]
def self.up
create_table :messages do |t|
t.string :author

View File

@@ -1,4 +1,4 @@
class AddMessageId < ActiveRecord::Migration
class AddMessageId < ActiveRecord::Migration[5.2]
def self.up
add_column :keyvalues, :message_id, :integer, :default => 0
end

View File

@@ -1,4 +1,4 @@
class CreateNodes < ActiveRecord::Migration
class CreateNodes < ActiveRecord::Migration[5.2]
def self.up
create_table :nodes do |t|
t.string :color, :default => 'red'

View File

@@ -1,4 +1,4 @@
class CreateWays < ActiveRecord::Migration
class CreateWays < ActiveRecord::Migration[5.2]
def self.up
create_table :ways do |t|
t.string :color, :default => 'red'

View File

@@ -1,4 +1,4 @@
class CreateSms < ActiveRecord::Migration
class CreateSms < ActiveRecord::Migration[5.2]
def self.up
# create_table "frontline_actions_triggers", :id => false, :force => true do |t|
# t.integer "action_id"

View File

@@ -1,4 +1,4 @@
class AddNameDescNodesWays < ActiveRecord::Migration
class AddNameDescNodesWays < ActiveRecord::Migration[5.2]
def self.up
add_column :ways, :name, :string, :default => ""
add_column :ways, :description, :string, :default => ""

View File

@@ -1,4 +1,4 @@
class ChangeLatLonTypes < ActiveRecord::Migration
class ChangeLatLonTypes < ActiveRecord::Migration[5.2]
def self.up
drop_table :ways
drop_table :nodes

View File

@@ -1,4 +1,4 @@
class AddWayComplete < ActiveRecord::Migration
class AddWayComplete < ActiveRecord::Migration[5.2]
def self.up
add_column :ways, :complete, :boolean, :default => true
end

View File

@@ -1,4 +1,4 @@
class CreateMaps < ActiveRecord::Migration
class CreateMaps < ActiveRecord::Migration[5.2]
def self.up
create_table :maps do |t|
t.string :name, :default => ''

View File

@@ -1,4 +1,4 @@
class CreateWarpables < ActiveRecord::Migration
class CreateWarpables < ActiveRecord::Migration[5.2]
def self.up
create_table :warpables do |t|
t.column :parent_id, :integer

View File

@@ -1,4 +1,4 @@
class AddMapId < ActiveRecord::Migration
class AddMapId < ActiveRecord::Migration[5.2]
def self.up
add_column :warpables, :map_id, :integer, :default => 0
end

View File

@@ -1,4 +1,4 @@
class AddMapDescriptionAuthor < ActiveRecord::Migration
class AddMapDescriptionAuthor < ActiveRecord::Migration[5.2]
def self.up
add_column :maps, :description, :text, :default => ''
add_column :maps, :author, :string, :default => 'anonymous'

View File

@@ -1,4 +1,4 @@
class AddWarperData < ActiveRecord::Migration
class AddWarperData < ActiveRecord::Migration[5.2]
def self.up
add_column :warpables, :nodes, :string, :default => ''
end

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