Adding rubocop sample config (#547)

* Adding rubocop sample config

* Removing double_quotes enforcement

* Using same rubocop yaml as in Plots2

* Autofixing rubocop offenses

* Fixing conditions for CC

Co-Authored-By: Sasha Boginsky <41092741+sashadev-sky@users.noreply.github.com>

* Adding Performance cop and fixing some offenses

* Fixing rubocop offenses and warnings

* Downgrading rubocop version since https://github.com/publiclab/mapknitter/pull/547#issuecomment-497359929
This commit is contained in:
Álax de Carvalho Alves
2019-06-01 12:30:56 -03:00
committed by Jeffrey Warren
parent dc69769bec
commit 713e387bdb
29 changed files with 1708 additions and 297 deletions

View File

@@ -2,6 +2,7 @@ version: 2
plugins:
rubocop:
enabled: true
channel: rubocop-0-70
brakeman:
enabled: true
bundler-audit:

79
.rubocop.yml Normal file
View File

@@ -0,0 +1,79 @@
# Start with Spotifys style guide as a base then customize from there
inherit_from:
- .rubocop_shopify_styleguide.yml
- .rubocop_todo.yml
# Apply rule to all cops
AllCops:
Include:
- '*/**/*.rb'
- '/Rakefile'
- '/config.ru'
Exclude:
- 'vendor/*'
- 'spec/**/*'
- 'bin/*'
- 'doc/*'
- 'log/*'
- 'db/**/*'
- 'Gemfile'
- 'Rakefile'
- 'config/**/*'
- 'script/**/*'
- 'lib/**/*'
- 'test/**/*'
- 'public/**/*'
- 'Dangerfile'
- 'app/views/**/*'
TargetRubyVersion: '2.4'
Layout/MultilineMethodCallIndentation:
Enabled: false
Style/RegexpLiteral:
Enabled: false
Style/IfInsideElse:
Enabled: false
Style/DateTime:
Enabled: false
Style/CaseEquality:
Enabled: false
Style/FrozenStringLiteralComment:
Enabled: false
Lint/ParenthesesAsGroupedExpression:
Enabled: false
Layout/EndAlignment:
Enabled: false
Layout/DefEndAlignment:
Enabled: false
Lint/SafeNavigationChain:
Enabled: false
Lint/AssignmentInCondition:
Enabled: false
Naming/AccessorMethodName:
Enabled: false
Metrics/ClassLength:
Enabled: false
Metrics/ParameterLists:
Enabled: false
Style/StringLiterals:
Enabled: false
Metrics/LineLength:
Max: 423
Style/Documentation:
Enabled: false

File diff suppressed because it is too large Load Diff

142
.rubocop_todo.yml Normal file
View File

@@ -0,0 +1,142 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2019-03-02 16:51:15 +0100 using RuboCop version 0.65.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 180
Metrics/AbcSize:
Max: 178
# Offense count: 13
# Configuration parameters: CountComments, ExcludedMethods.
# ExcludedMethods: refine
Metrics/BlockLength:
Max: 257
# Offense count: 24
# Configuration parameters: CountBlocks.
Metrics/BlockNesting:
Max: 6
# Offense count: 50
Metrics/CyclomaticComplexity:
Max: 28
# Offense count: 171
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/MethodLength:
Max: 86
# Offense count: 2
# Configuration parameters: CountComments.
Metrics/ModuleLength:
Max: 347
# Offense count: 60
Metrics/PerceivedComplexity:
Max: 33
# Offense count: 7
# Configuration parameters: EnforcedStyle.
# SupportedStyles: snake_case, camelCase
Naming/MethodName:
Exclude:
- 'app/controllers/tag_controller.rb'
- 'app/models/doc_list.rb'
- 'app/models/search_request.rb'
- 'app/services/search_service.rb'
# Offense count: 8
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist, MethodDefinitionMacros.
# NamePrefix: is_, has_, have_
# NamePrefixBlacklist: is_, has_, have_
# NameWhitelist: is_a?
# MethodDefinitionMacros: define_method, define_singleton_method
Naming/PredicateName:
Exclude:
- 'spec/**/*'
- 'app/controllers/openid_controller.rb'
- 'app/models/drupal_file.rb'
- 'app/models/image.rb'
- 'app/models/node.rb'
- 'app/models/revision.rb'
- 'app/models/tag.rb'
- 'app/models/user.rb'
# Offense count: 3
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
# AllowedNames: io, id, to, by, on, in, at, ip, db
Naming/UncommunicativeMethodParamName:
Exclude:
- 'app/models/doc_list.rb'
# Offense count: 9
# Configuration parameters: EnforcedStyle.
# SupportedStyles: snake_case, camelCase
Naming/VariableName:
Exclude:
- 'app/models/concerns/node_shared.rb'
- 'app/models/doc_list.rb'
- 'app/models/revision.rb'
- 'app/models/search_request.rb'
# Offense count: 2
Security/Open:
Exclude:
- 'app/models/image.rb'
- 'app/models/node.rb'
# Offense count: 26
# Configuration parameters: MinBodyLength.
Style/GuardClause:
Exclude:
- 'app/controllers/admin_controller.rb'
- 'app/controllers/application_controller.rb'
- 'app/controllers/features_controller.rb'
- 'app/controllers/notes_controller.rb'
- 'app/controllers/openid_controller.rb'
- 'app/controllers/users_controller.rb'
- 'app/helpers/application_helper.rb'
- 'app/helpers/comment_helper.rb'
- 'app/models/comment.rb'
- 'app/models/node.rb'
- 'app/models/spamaway.rb'
- 'app/models/user.rb'
- 'app/models/user_tag.rb'
- 'app/services/search_criteria.rb'
# Offense count: 2
Style/IdenticalConditionalBranches:
Exclude:
# - 'app/controllers/answers_controller.rb'
# Offense count: 45
# Cop supports --auto-correct.
Style/IfUnlessModifier:
Enabled: false
# Offense count: 1
Style/MixinUsage:
Exclude:
- 'app/controllers/application_controller.rb'
# Offense count: 16
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
# SupportedStyles: predicate, comparison
Style/NumericPredicate:
Exclude:
- 'spec/**/*'
- 'app/controllers/application_controller.rb'
- 'app/controllers/users_controller.rb'
- 'app/controllers/wiki_controller.rb'
- 'app/jobs/digest_mail_job.rb'
- 'app/models/comment.rb'
- 'app/models/concerns/statistics.rb'
- 'app/models/user.rb'

View File

@@ -40,6 +40,7 @@ group :dependencies do
end
group :test do
gem "rubocop", '~> 0.52.0'
gem 'simplecov', require: false
gem 'simplecov-cobertura', require: false
gem 'test-unit'

View File

@@ -32,6 +32,7 @@ GEM
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
arel (3.0.3)
ast (2.4.0)
autoprefixer-rails (9.5.1.1)
execjs
aws-sdk (1.5.8)
@@ -51,7 +52,7 @@ GEM
execjs (2.7.0)
faker (1.9.3)
i18n (>= 0.7)
ffi (1.10.0)
ffi (1.11.1)
friendly_id (4.0.10.1)
activerecord (>= 3.0, < 4.0)
geokit (1.13.1)
@@ -96,12 +97,16 @@ GEM
cocaine (~> 0.5.5)
mime-types
mimemagic (= 0.3.0)
parallel (1.17.0)
parser (2.6.3.0)
ast (~> 2.4.0)
passenger (6.0.2)
rack
rake (>= 0.8.1)
polyglot (0.3.5)
popper_js (1.14.5)
power_assert (1.1.4)
powerpack (0.1.2)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
@@ -132,6 +137,7 @@ GEM
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
rainbow (3.0.0)
rake (12.3.2)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
@@ -145,9 +151,17 @@ GEM
right_aws (3.1.0)
right_http_connection (>= 1.2.5)
right_http_connection (1.5.0)
rubocop (0.52.1)
parallel (~> 1.10)
parser (>= 2.4.0.2, < 3.0)
powerpack (~> 0.1)
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-openid (2.7.0)
ruby-openid-apps-discovery (1.2.0)
ruby-openid (>= 2.1.7)
ruby-progressbar (1.10.1)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
@@ -181,6 +195,7 @@ GEM
tzinfo (0.3.55)
uglifier (4.1.20)
execjs (>= 0.3.0, < 3)
unicode-display_width (1.6.0)
uuidtools (2.1.5)
will_paginate (3.1.7)
will_paginate-bootstrap4 (0.2.2)
@@ -212,6 +227,7 @@ DEPENDENCIES
rdiscount (= 2.2.0.1)
recaptcha
right_aws
rubocop (~> 0.52.0)
ruby-openid (~> 2.5)
sass
simplecov
@@ -229,4 +245,4 @@ RUBY VERSION
ruby 2.4.6p354
BUNDLED WITH
1.17.3
1.16.6

View File

@@ -12,7 +12,7 @@ class AnnotationsController < ApplicationController
geojson = params[:annotation]
respond_to do |format|
format.json {
format.json do
@annotation = @map.annotations.create(
annotation_type: geojson[:properties][:annotation_type],
coordinates: geojson[:geometry][:coordinates],
@@ -21,7 +21,7 @@ class AnnotationsController < ApplicationController
)
@annotation.user_id = current_user.id if logged_in?
redirect_to map_annotation_url(@map, @annotation) if @annotation.save
}
end
end
end
@@ -33,7 +33,8 @@ class AnnotationsController < ApplicationController
def update
@annotation = Annotation.find params[:id]
geojson = params[:annotation]
if @annotation.user_id.nil? || current_user.can_edit?(@annotation)
return if @annotation.user_id.nil? || current_user.can_edit?(@annotation)
Annotation.update(@annotation.id,
coordinates: geojson[:geometry][:coordinates],
text: geojson[:properties][:textContent],
@@ -41,7 +42,6 @@ class AnnotationsController < ApplicationController
render file: 'annotations/update.json.erb',
content_type: 'application/json'
end
end
def destroy
@annotation = Annotation.find params[:id]

View File

@@ -14,7 +14,7 @@ class ApplicationController < ActionController::Base
if user_id
begin
@user = User.find(user_id)
rescue
rescue StandardError
@user = nil
end
else
@@ -41,13 +41,14 @@ class ApplicationController < ActionController::Base
begin
user_id && User.find(user_id) ? true : false
rescue
rescue StandardError
return false
end
end
def save_tags(map)
return unless params[:tags].present?
params[:tags].tr(' ', ',').split(',').each do |tagname|
map.add_tag(tagname.strip, current_user)
end

View File

@@ -2,7 +2,7 @@ class ExportController < ApplicationController
protect_from_forgery except: :formats
def index
@exports = Export.where('status NOT IN (?)', %w[failed complete none])
@exports = Export.where('status NOT IN (?)', %w(failed complete none))
.order('updated_at DESC')
@day = Export.where(status: 'complete')
.where('updated_at > (?)', (Time.now - 1.day).to_s(:db))
@@ -51,18 +51,18 @@ class ExportController < ApplicationController
def progress
map = Map.find params[:id]
export = map.export
if export.present?
output = if export.present?
if export.status == 'complete'
output = 'complete'
'complete'
elsif export.status == 'none'
output = 'export not running'
'export not running'
elsif export.status == 'failed'
output = 'export failed'
'export failed'
else
output = export.status
export.status
end
else
output = 'export has not been run'
'export has not been run'
end
render text: output, layout: false
end

View File

@@ -1,11 +1,11 @@
class FeedsController < ApplicationController
before_filter :query, only: %i[clean license]
before_filter :query, only: %i(clean license)
def all
# (Warpable.all + Map.all).sort_by(&:created_at)
@maps = Map.find(:all, order: 'id DESC', limit: 20,
conditions: { archived: false, password: '' },
joins: %i[user warpables],
joins: %i(user warpables),
group: 'maps.id')
render layout: false, template: 'feeds/all'
response.headers['Content-Type'] = 'application/xml; charset=utf-8'

View File

@@ -3,7 +3,7 @@ class ImagesController < ApplicationController
rescue_from Errno::ENOENT, Errno::ETIMEDOUT,
OpenURI::HTTPError, Timeout::Error,
with: :url_upload_not_found
protect_from_forgery except: %i[update delete]
protect_from_forgery except: %i(update delete)
# Convert model to json without including root name. Eg. 'warpable'
ActiveRecord::Base.include_root_in_json = false
@@ -21,7 +21,6 @@ class ImagesController < ApplicationController
end
end
# rubocop:disable LineLength
# assign attributes directly after rails update
def create
@warpable = Warpable.new
@@ -41,7 +40,6 @@ class ImagesController < ApplicationController
end
end
end
# rubocop:enable LineLength
# mapknitter.org/import/<map-name>/?url=http://myurl.com/image.jpg
def import

View File

@@ -1,10 +1,9 @@
# rubocop:disable LineLength
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 export exports destroy]
before_filter :require_login, only: %i(edit update destroy)
before_filter :find_map, only: %i(show annotate embed edit update images export exports destroy)
layout 'knitter2'
@@ -202,4 +201,3 @@ class MapsController < ApplicationController
@map = Map.find(params[:id])
end
end
# rubocop:enable LineLength

View File

@@ -1,11 +1,11 @@
require 'uri'
require 'cgi'
# This controller handles the login/logout function of the site.
class SessionsController < ApplicationController
# protect_from_forgery :except => [:create]
@@openid_url_base = "https://publiclab.org/people/"
@@openid_url_suffix = "/identity"
@openid_url_base = "https://publiclab.org/people/"
@openid_url_suffix = "/identity"
def new
if logged_in?
@@ -19,28 +19,28 @@ class SessionsController < ApplicationController
back_to = params[:back_to]
# we pass a temp username; on line 75 it'll be overwritten by the real one in PublicLab.org's response:
open_id = "x"
openid_url = URI.decode(open_id)
openid_url = CGI.unescape(open_id)
# here it is localhost:3000/people/admin/identity for admin
# possibly user is providing the whole URL
if openid_url.include? "publiclab"
if openid_url.include? "http"
# params[:subaction] contains the value of the provider
# provider implies ['github', 'google_oauth2', 'twitter', 'facebook']
if params[:subaction]
url = if params[:subaction]
# provider based authentication
url = openid_url + "/" + params[:subaction]
openid_url + "/" + params[:subaction]
else
# form based authentication
url = openid_url
openid_url
end
end
else
if params[:subaction]
url = if params[:subaction]
# provider based authentication
url = @@openid_url_base + openid_url + @@openid_url_suffix + "/" + params[:subaction]
@openid_url_base + openid_url + @openid_url_suffix + "/" + params[:subaction]
else
# form based authentication
url = @@openid_url_base + openid_url + @@openid_url_suffix
@openid_url_base + openid_url + @openid_url_suffix
end
end
openid_authentication(url, back_to)
@@ -67,7 +67,7 @@ class SessionsController < ApplicationController
def openid_authentication(openid_url, back_to)
# puts openid_url
authenticate_with_open_id(openid_url, :required => [:nickname, :email, :fullname]) do |result, identity_url, registration|
authenticate_with_open_id(openid_url, required: %i(nickname email fullname)) do |result, identity_url, registration|
dummy_identity_url = identity_url
dummy_identity_url = dummy_identity_url.split('/')
if dummy_identity_url.include?('github') || dummy_identity_url.include?('google_oauth2') || dummy_identity_url.include?('facebook') || dummy_identity_url.include?('twitter')
@@ -77,7 +77,7 @@ class SessionsController < ApplicationController
identity_url = identity_url.split('/')[0..-2].join('/') + '/' + registration['nickname']
if result.successful?
@user = User.find_by_identity_url(identity_url)
if not @user
unless @user
@user = User.new
@user.login = registration['nickname']
@user.email = registration['email']
@@ -87,8 +87,8 @@ class SessionsController < ApplicationController
@user.role = hash[1].split('=')[1]
begin
@user.save!
rescue ActiveRecord::RecordInvalid => invalid
puts invalid
rescue ActiveRecord::RecordInvalid => e
puts e
failed_login "User can not be associated to local account. Probably the account already exists with different capitalization!"
return
end

View File

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

View File

@@ -27,5 +27,4 @@ class UsersController < ApplicationController
def sort_direction
params[:direction] || 'desc'
end
end

View File

@@ -1,11 +1,10 @@
module ApplicationHelper
def current_user
user_id = session[:user_id]
if user_id
begin
@user = User.find(user_id)
rescue
rescue StandardError
@user = nil
end
else
@@ -19,14 +18,14 @@ module ApplicationHelper
html = ""
unless object.nil? || object.errors.blank?
html << "<div class='alert alert-error #{object.class.name.humanize.downcase}Errors'>\n"
if message.blank?
html << if message.blank?
if object.new_record?
html << "\t\t<h5>There was a problem creating the #{object.class.name.humanize.downcase}</h5>\n"
"\t\t<h5>There was a problem creating the #{object.class.name.humanize.downcase}</h5>\n"
else
html << "\t\t<h5>There was a problem updating the #{object.class.name.humanize.downcase}</h5>\n"
"\t\t<h5>There was a problem updating the #{object.class.name.humanize.downcase}</h5>\n"
end
else
html << "<h5>#{message}</h5>"
"<h5>#{message}</h5>"
end
html << "\t\t<ul>\n"
object.errors.full_messages.each do |error|
@@ -42,10 +41,9 @@ 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)
out << %(<meta name="csrf-token" content="%s"/>)
out % [ Rack::Utils.escape_html(request_forgery_protection_token),
Rack::Utils.escape_html(form_authenticity_token) ]
out = %(<meta name="csrf-param" content="%s"/>\n) # rubocop:disable Style/FormatStringToken
out << %(<meta name="csrf-token" content="%s"/>) # rubocop:disable Style/FormatStringToken
format(out, Rack::Utils.escape_html(request_forgery_protection_token), Rack::Utils.escape_html(form_authenticity_token))
end
end
@@ -54,5 +52,4 @@ module ApplicationHelper
direction = column == sort_column && sort_direction == 'asc' ? 'desc' : 'asc'
link_to title, sort: column, direction: direction
end
end

View File

@@ -0,0 +1,90 @@
module UsersHelper
#
# Use this to wrap view elements that the user can't access.
# !! Note: this is an *interface*, not *security* feature !!
# You need to do all access control at the controller level.
#
# Example:
# <%= if_authorized?(:index, User) do link_to('List all users', users_path) end %> |
# <%= if_authorized?(:edit, @user) do link_to('Edit this user', edit_user_path) end %> |
# <%= if_authorized?(:destroy, @user) do link_to 'Destroy', @user, :confirm => 'Are you sure?', :method => :delete end %>
#
#
def if_authorized?(action, resource)
yield(action, resource) if authorized?(action, resource)
end
#
# Link to user's page ('users/1')
#
# By default, their login is used as link text and link title (tooltip)
#
# Takes options
# * :content_text => 'Content text in place of user.login', escaped with
# the standard h() function.
# * :content_method => :user_instance_method_to_call_for_content_text
# * :title_method => :user_instance_method_to_call_for_title_attribute
# * as well as link_to()'s standard options
#
# Examples:
# link_to_user @user
# # => <a href="/users/3" title="barmy">barmy</a>
#
# # if you've added a .name attribute:
# content_tag :span, :class => :vcard do
# (link_to_user user, :class => 'fn n', :title_method => :login, :content_method => :name) +
# ': ' + (content_tag :span, user.email, :class => 'email')
# end
# # => <span class="vcard"><a href="/users/3" title="barmy" class="fn n">Cyril Fotheringay-Phipps</a>: <span class="email">barmy@blandings.com</span></span>
#
# link_to_user @user, :content_text => 'Your user page'
# # => <a href="/users/3" title="barmy" class="nickname">Your user page</a>
#
def link_to_user(user, options = {})
raise "Invalid user" unless user
options.reverse_merge! content_method: :login, title_method: :login, class: :nickname
content_text = options.delete(:content_text)
content_text ||= user.send(options.delete(:content_method))
options[:title] ||= user.send(options.delete(:title_method))
link_to h(content_text), user_path(user), options
end
#
# Link to login page using remote ip address as link content
#
# The :title (and thus, tooltip) is set to the IP address
#
# Examples:
# link_to_login_with_IP
# # => <a href="/login" title="169.69.69.69">169.69.69.69</a>
#
# link_to_login_with_IP :content_text => 'not signed in'
# # => <a href="/login" title="169.69.69.69">not signed in</a>
#
def link_to_login_with_IP(content_text = nil, options = {}) # rubocop:disable Naming/MethodName
ip_addr = request.remote_ip
content_text ||= ip_addr
options.reverse_merge! title: ip_addr
if tag = options.delete(:tag)
content_tag tag, h(content_text), options
else
link_to h(content_text), login_path, options
end
end
#
# Link to the current user's page (using link_to_user) or to the login page
# (using link_to_login_with_IP).
#
def link_to_current_user(options = {})
if current_user
link_to_user current_user, options
else
content_text = options.delete(:content_text) || 'not signed in'
# kill ignored options from link_to_user
%i(content_method title_method).each { |opt| options.delete(opt) }
link_to_login_with_IP content_text, options
end
end
end

View File

@@ -5,7 +5,6 @@ class CommentMailer < ActionMailer::Base
def notify(user, comment)
@user = user
@comment = comment
mail(:to => user.email, :subject => "New comment on '"+comment.map.name+"'")
mail(to: user.email, subject: "New comment on '" + comment.map.name + "'")
end
end

View File

@@ -8,21 +8,21 @@ class Annotation < ActiveRecord::Base
serialize :style, Hash
def author
User.find(self.user_id).login
User.find(user_id).login
end
def geometry_type
case self.annotation_type
geometry_type = case annotation_type
when 'polyline' then
geometry_type = 'LineString'
'LineString'
when 'polygon' then
geometry_type = 'Polygon'
'Polygon'
when 'rectangle' then
geometry_type = 'Polygon'
'Polygon'
else
geometry_type = 'Point'
'Point'
end
return geometry_type
geometry_type
end
end

View File

@@ -1,5 +1,4 @@
class Comment < ActiveRecord::Base
attr_accessible :user_id, :body
belongs_to :map
@@ -8,6 +7,6 @@ class Comment < ActiveRecord::Base
validates_presence_of :body, :user_id, :map_id
def author
User.find(self.user_id).login
User.find(user_id).login
end
end

View File

@@ -6,16 +6,16 @@ class Export < ActiveRecord::Base
# currently exporting?
def running?
!(['complete','none','failed'].include? self.status)
!(%w(complete none failed).include? status)
end
def self.average_cm_per_pixel
e = Export.find :all, :conditions => ['cm_per_pixel != "" AND cm_per_pixel < 500']
e = Export.find :all, conditions: ['cm_per_pixel != "" AND cm_per_pixel < 500']
sum = 0
e.each do |export|
sum += export.cm_per_pixel
end
if e.length > 0
if !e.empty?
sum / e.length
else
0
@@ -23,8 +23,8 @@ class Export < ActiveRecord::Base
end
def self.histogram_cm_per_pixel
e = Export.find :all, :conditions => ['cm_per_pixel != "" AND cm_per_pixel < 500'], :order => "cm_per_pixel DESC"
if e.length > 0
e = Export.find :all, conditions: ['cm_per_pixel != "" AND cm_per_pixel < 500'], order: "cm_per_pixel DESC"
if !e.empty?
hist = []
(0..e.first.cm_per_pixel.to_i).each do |bin|
hist[bin] = 0
@@ -42,7 +42,7 @@ class Export < ActiveRecord::Base
e = Export.where('cm_per_pixel != "" AND cm_per_pixel < 500')
.order(cm_per_pixel: 'desc')
hist = []
(0..(e.first.cm_per_pixel)/10.to_i).each do |bin|
(0..e.first.cm_per_pixel / 10.to_i).each do |bin|
hist[bin] = 0
end
e.each do |export|
@@ -52,11 +52,11 @@ class Export < ActiveRecord::Base
end
def self.export_count
Export.count :all, :conditions => ['status != "failed" AND status != "complete" AND status != "none" AND updated_at > ?', (DateTime.now-24.hours).to_s(:db)]
Export.count :all, conditions: ['status != "failed" AND status != "complete" AND status != "none" AND updated_at > ?', (DateTime.now - 24.hours).to_s(:db)]
end
# all exports currently running
def self.exporting
Export.find :all, :conditions => ['status != "failed" AND status != "complete" AND status != "none" AND updated_at > ?', (DateTime.now-24.hours).to_s(:db)]
Export.find :all, conditions: ['status != "failed" AND status != "complete" AND status != "none" AND updated_at > ?', (DateTime.now - 24.hours).to_s(:db)]
end
end

View File

@@ -1,7 +1,7 @@
class Map < ActiveRecord::Base
include ActiveModel::Validations
extend FriendlyId
friendly_id :name, :use => [:slugged, :static]
friendly_id :name, use: %i(slugged static)
attr_accessible :author, :name, :slug, :lat, :lon,
:location, :description, :zoom, :license
@@ -26,10 +26,10 @@ class Map < ActiveRecord::Base
# }
validates :lat, :lon, NotAtOrigin: true
has_many :exports, :dependent => :destroy
has_many :tags, :dependent => :destroy
has_many :comments, :dependent => :destroy
has_many :annotations, :dependent => :destroy
has_many :exports, dependent: :destroy
has_many :tags, dependent: :destroy
has_many :comments, dependent: :destroy
has_many :annotations, dependent: :destroy
belongs_to :user
scope :active, -> { where(archived: false) }
@@ -38,11 +38,11 @@ class Map < ActiveRecord::Base
has_many :warpables do
def public_filenames
filenames = {}
self.each do |warpable|
each do |warpable|
filenames[warpable.id] = {}
sizes = Array.new(Warpable::THUMBNAILS.keys).push(nil)
sizes.each do |size|
key = size != nil ? size : "original"
key = !size.nil? ? size : "original"
filenames[warpable.id][key] = warpable.public_filename(size)
end
end
@@ -51,25 +51,24 @@ class Map < ActiveRecord::Base
end
def validate
self.name != 'untitled'
self.lat >= -90 && self.lat <= 90 && self.lon >= -180 && self.lat <= 180
lat >= -90 && lat <= 90 && lon >= -180 && lat <= 180 if name != 'untitled'
end
# Hash the password before saving the record
def before_create
self.password = Password::update(self.password) if self.password != ""
self.password = Password.update(password) if password != ""
end
def placed_warpables
self.warpables.where('width > 0 AND nodes <> ""')
warpables.where('width > 0 AND nodes <> ""')
end
def private
self.password != ""
password != ""
end
def anonymous?
self.author == "" || self.user_id == 0
author == "" || user_id.zero?
end
def self.bbox(minlat, minlon, maxlat, maxlon)
@@ -78,15 +77,15 @@ class Map < ActiveRecord::Base
end
def exporting?
self.export && self.export.running?
export&.running?
end
def export
self.latest_export
latest_export
end
def latest_export
self.exports.last
exports.last
end
def self.authors(limit = 50)
@@ -96,12 +95,12 @@ class Map < ActiveRecord::Base
.collect(&:author)
end
def self.search(q)
q = q.squeeze(' ').strip
def self.search(query)
query = query.squeeze(' ').strip
Map.active
.where(['author LIKE ? OR name LIKE ?
OR location LIKE ? OR description LIKE ?',
"%#{q}%", "%#{q}%", "%#{q}%", "%#{q}%"])
"%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%"])
end
def self.featured
@@ -149,7 +148,7 @@ class Map < ActiveRecord::Base
def nodes
nodes = {}
self.warpables.each do |warpable|
warpables.each do |warpable|
if warpable.nodes
w_nodes = []
warpable.nodes.split(',').each do |node|
@@ -165,13 +164,14 @@ class Map < ActiveRecord::Base
# find all other maps within <dist> degrees lat or lon
def nearby_maps(dist)
return [] if self.lat.to_f == 0.0 || self.lon.to_f == 0.0
return [] if lat.to_f == 0.0 || lon.to_f == 0.0
Map.find(
:all,
limit: 10,
conditions: [
'id != ? AND lat > ? AND lat < ? AND lon > ? AND lon < ?',
self.id,self.lat-dist,self.lat+dist,self.lon-dist,self.lon+dist
id, lat - dist, lat + dist, lon - dist, lon + dist
]
)
end
@@ -180,7 +180,7 @@ class Map < ActiveRecord::Base
# determine optimal zoom level
puts '> calculating scale'
pxperms = []
self.placed_warpables.each do |warpable|
placed_warpables.each do |warpable|
pxperms << 100.00 / warpable.cm_per_pixel if warpable.placed?
end
average = (pxperms.inject { |sum, n| sum + n }) / pxperms.length
@@ -188,7 +188,7 @@ class Map < ActiveRecord::Base
end
def best_cm_per_pixel
hist = self.images_histogram
hist = images_histogram
scores = []
(0..(hist.length - 1)).each do |i|
scores[i] = 0
@@ -206,14 +206,14 @@ class Map < ActiveRecord::Base
end
def average_cm_per_pixel
if self.warpables.length > 0
if !warpables.empty?
scales = []
count = 0
self.placed_warpables.each do |warpable|
placed_warpables.each do |warpable|
count += 1
res = warpable.cm_per_pixel
res = 1 if res == 0 # let's not ever try to go for infinite resolution
scales << res unless res == nil
res = 1 if res.zero? # let's not ever try to go for infinite resolution
scales << res unless res.nil?
end
total_sum = (scales.inject { |sum, n| sum + n }) if scales
return total_sum / count if total_sum
@@ -225,13 +225,13 @@ class Map < ActiveRecord::Base
# for sparklines graph display
def images_histogram
hist = []
self.warpables.each do |warpable|
warpables.each do |warpable|
res = warpable.cm_per_pixel.to_i
hist[res] = 0 if hist[res] == nil
hist[res] = 0 if hist[res].nil?
hist[res] += 1
end
(0..hist.length - 1).each do |bin|
hist[bin] = 0 if hist[bin] == nil
hist[bin] = 0 if hist[bin].nil?
end
hist
end
@@ -239,16 +239,16 @@ class Map < ActiveRecord::Base
# for sparklines graph display
def grouped_images_histogram(binsize)
hist = []
self.warpables.each do |warpable|
warpables.each do |warpable|
res = warpable.cm_per_pixel
if res != nil
next if res.nil?
res = (warpable.cm_per_pixel / (0.001 + binsize)).to_i
hist[res] = 0 if hist[res] == nil
hist[res] = 0 if hist[res].nil?
hist[res] += 1
end
end
(0..hist.length - 1).each do |bin|
hist[bin] = 0 if hist[bin] == nil
hist[bin] = 0 if hist[bin].nil?
end
hist
end
@@ -261,38 +261,36 @@ class Map < ActiveRecord::Base
Exporter.run_export(user,
resolution,
self.export || new_export,
self.id,
self.slug,
export || new_export,
id,
slug,
Rails.root.to_s,
self.average_scale,
self.placed_warpables,
average_scale,
placed_warpables,
key)
end
def after_create
puts 'saving Map'
if last = Map.find_by_name(self.slug,:order => "version DESC")
return unless Map.find_by_name(slug, order: "version DESC")
self.version = last.version + 1
end
end
def license_link
if self.license == "cc-by"
if license == "cc-by"
"<a href='http://creativecommons.org/licenses/by/3.0/'>Creative Commons Attribution 3.0 Unported License</a>"
elsif self.license == "publicdomain"
elsif license == "publicdomain"
"<a href='http://creativecommons.org/publicdomain/zero/1.0/'>Public Domain</a>"
end
end
def has_tag(tagname)
Tag.find(:all, :conditions => { :map_id => self.id, :name => tagname }).length > 0
!Tag.find(:all, conditions: { map_id: id, name: tagname }).empty?
end
def add_tag(tagname, user)
tagname = tagname.downcase
unless self.has_tag(tagname)
self.tags.create(name: tagname, user_id: user.id, map_id: id)
end
tags.create(name: tagname, user_id: user.id, map_id: id) unless has_tag(tagname)
end
end

View File

@@ -1,15 +1,14 @@
class Tag < ActiveRecord::Base
belongs_to :map
belongs_to :user
attr_accessible :name, :map_id, :user_id
validates_presence_of :name, :on => :create, :message => "can't be blank"
validates_presence_of :user_id, :on => :create, :message => "can't be blank"
validates_presence_of :map_id, :on => :create, :message => "can't be blank"
validates_presence_of :name, on: :create, message: "can't be blank"
validates_presence_of :user_id, on: :create, message: "can't be blank"
validates_presence_of :map_id, on: :create, message: "can't be blank"
def maps
Map.where(id: Tag.where(name: self.name).collect(&:map_id).uniq)
Map.where(id: Tag.where(name: name).collect(&:map_id).uniq)
end
end

View File

@@ -1,22 +1,21 @@
require 'digest/sha1'
class User < ActiveRecord::Base
has_many :maps
has_many :tags
has_many :comments
has_many :exports
validates_presence_of :login
validates_length_of :login, :within => 3..40
validates_length_of :login, within: 3..40
validates_uniqueness_of :login
validates_length_of :name, :maximum => 100
validates_length_of :name, maximum: 100
validates_presence_of :email
validates_length_of :email, :within => 6..100 #r@a.wk
validates_length_of :email, within: 6..100 # r@a.wk
validates_uniqueness_of :email
# HACK HACK HACK -- how to do attr_accessible from here?
# HACK: HACK HACK -- how to do attr_accessible from here?
# prevents a user from submitting a crafted form that bypasses activation
# anything else you want your user to change should be added here.
attr_accessible :login, :email, :name, :password, :password_confirmation
@@ -29,8 +28,9 @@ class User < ActiveRecord::Base
#
def self.authenticate(login, password)
return nil if login.blank? || password.blank?
u = find_by_login(login.downcase) # need to get the salt
u && u.authenticated?(password) ? u : nil
u&.authenticated?(password) ? u : nil
end
def login=(value)
@@ -42,24 +42,24 @@ class User < ActiveRecord::Base
end
def last_action
self.maps.order('updated_at DESC').limit(1).first.updated_at
maps.order('updated_at DESC').limit(1).first.updated_at
end
# Permissions for editing and deleting resources
def owns?(resource)
resource.user_id.to_i == self.id
resource.user_id.to_i == id
end
def owns_map?(resource)
resource.respond_to?(:map) && resource.map.user_id.to_i == self.id
resource.respond_to?(:map) && resource.map.user_id.to_i == id
end
def can_delete?(resource)
self.owns?(resource) || self.owns_map?(resource) || self.role == "admin"
owns?(resource) || owns_map?(resource) || role == "admin"
end
def can_edit?(resource)
self.owns?(resource)
owns?(resource)
end
end

View File

@@ -5,38 +5,39 @@ class Warpable < ActiveRecord::Base
# 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"]
validates_attachment_content_type :image, content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"]
belongs_to :map
belongs_to :user
# overriding JSON formatting for Leaflet.DistortableImage
def as_json(options = {})
super options.merge(methods: [:src, :srcmedium])
super options.merge(methods: %i(src srcmedium))
end
# JSON formatting for file upload plugin
def fup_json
{ "name" => read_attribute(:image_filename),
"size" => read_attribute(:image_size),
"url" => self.image.url(:medium),
"original_url" => self.image.url(:original),
"id" => self.read_attribute(:id),
"thumbnail_url" => self.image.url(:thumb),
"delete_url" => self.image.url,
"url" => image.url(:medium),
"original_url" => image.url(:original),
"id" => read_attribute(:id),
"thumbnail_url" => image.url(:thumb),
"delete_url" => image.url,
"delete_type" => "DELETE" }
end
def fup_error_json
{ "name" => read_attribute(:image_filename),
"size" => read_attribute(:image_size),
"error" => self.errors["base"]}
"error" => errors["base"] }
end
after_save :save_dimensions
@@ -44,39 +45,39 @@ class Warpable < ActiveRecord::Base
# this runs each time warpable is moved/distorted,
# to calculate resolution
def save_dimensions
if Rails.env.production?
geo = Paperclip::Geometry.from_file(Paperclip.io_adapters.for(self.image.url)) # s3 version
geo = if Rails.env.production?
Paperclip::Geometry.from_file(Paperclip.io_adapters.for(image.url)) # s3 version
else
geo = Paperclip::Geometry.from_file(Paperclip.io_adapters.for(self.image).path) # local filesystem version
Paperclip::Geometry.from_file(Paperclip.io_adapters.for(image).path) # local filesystem version
end
# Rails >= v3.1 only
self.update_column(:width, geo.width)
self.update_column(:height, geo.height)
update_column(:width, geo.width)
update_column(:height, geo.height)
# Rails >= v4.0 only
# self.update_columns(attributes)
end
# if has non-nil width and has nodes, it's been placed.
def placed?
!self.width.nil? && self.nodes != ''
!width.nil? && nodes != ''
end
def poly_area
area = 0
nodes = self.nodes_array
nodes = nodes_array
nodes.each_with_index do |node, index|
if index < nodes.length-1
nextnode = nodes[index+1]
nextnode = if index < nodes.length - 1
nodes[index + 1]
else
nextnode = nodes[0]
nodes[0]
end
if index > 0
last = nodes[index-1]
last = if index.positive?
nodes[index - 1]
else
last = nodes[nodes.length-1]
nodes[nodes.length - 1]
end
scale = 20037508.34
scale = 20_037_508.34
# inefficient but workable, we don't use this that often:
nodey = Cartagen.spherical_mercator_lat_to_y(node.lat, scale)
@@ -93,23 +94,23 @@ class Warpable < ActiveRecord::Base
# crude measure based on image width, as resolution can vary
# across image if it's not flat on the earth
def get_cm_per_pixel
unless self.width.nil? || self.nodes == ''
nodes = self.nodes_array
unless width.nil? || nodes == ''
nodes = nodes_array
# haversine might be more appropriate for large images
scale = 20037508.34
scale = 20_037_508.34
y1 = Cartagen.spherical_mercator_lat_to_y(nodes[0].lat, scale)
x1 = Cartagen.spherical_mercator_lon_to_x(nodes[0].lon, scale)
y2 = Cartagen.spherical_mercator_lat_to_y(nodes[1].lat, scale)
x2 = Cartagen.spherical_mercator_lon_to_x(nodes[1].lon, scale)
dist = Math.sqrt(((y2 - y1) * (y2 - y1)) + ((x2 - x1) * (x2 - x1)))
scale = (dist*100)/(self.width) unless self.width.nil? || dist.nil?
scale = (dist * 100) / width unless width.nil? || dist.nil?
end
scale
end
def self.histogram_cm_per_pixel
w = Warpable.find :all, :conditions => ['cm_per_pixel != 0 AND cm_per_pixel < 500'], :order => "cm_per_pixel DESC"
if w.length > 0
w = Warpable.find :all, conditions: ['cm_per_pixel != 0 AND cm_per_pixel < 500'], order: "cm_per_pixel DESC"
if !w.empty?
hist = []
(0..w.first.cm_per_pixel.to_i).each do |bin|
hist[bin] = 0
@@ -124,7 +125,7 @@ class Warpable < ActiveRecord::Base
end
def nodes_array
Node.find self.nodes.split(',')
Node.find nodes.split(',')
end
# allow uploads via URL
@@ -132,8 +133,13 @@ class Warpable < ActiveRecord::Base
require 'open-uri'
attr_reader :url
def url=(uri)
return nil if uri.blank?
io = (open(URI.parse(uri)) rescue return nil)
nil if uri.blank?
io = (begin
URI.parse(uri).open
rescue StandardError
nil
end)
(class << io; self; end;).class_eval do
define_method(:original_filename) { base_uri.path.split('/').last }
end
@@ -146,18 +152,16 @@ class Warpable < ActiveRecord::Base
end
def user_id
Map.find self.map_id
Map.find map_id
map.user_id
end
private
# adjust filename behavior of Paperclip after migrating from attachment_fu
Paperclip.interpolates :custom_filename do |attachment, style|
if style == :original
custom_filename = basename(attachment,style) # generate hash path here
basename(attachment, style) # generate hash path here
else
custom_filename = "#{basename(attachment,style)}_#{style}" # generate hash path here
"#{basename(attachment, style)}_#{style}" # generate hash path here
end
end
end

View File

@@ -1,6 +1,6 @@
class Way < ActiveRecord::Base
attr_accessible :body, :lat, :lon, :map_id, :color
has_many :nodes, :dependent => :destroy
has_many :nodes, dependent: :destroy
def bbox=(bbox)
# counting from left, counter-clockwise

View File

@@ -1,4 +1,4 @@
<% if @map.exports.length == 0 || @map.exports.first.status == 'none' %>
<% if @map.exports.length.zero? || @map.exports.first.status == 'none' %>
<li class="dropdown-header">No export formats available</li>
<% else %>
<% if !@map.exports.first.jpg && !@map.exports.first.geotiff && !@map.exports.first.tms && !@map.exports.first.zip %>

View File

@@ -231,8 +231,8 @@ class Exporter
my_warpable_coords = warpable.generate_perspectival_distort(scale,slug)
puts '- '+my_warpable_coords.to_s
warpable_coords << my_warpable_coords
lowest_x = my_warpable_coords.first if (my_warpable_coords.first < lowest_x || lowest_x == 0)
lowest_y = my_warpable_coords.last if (my_warpable_coords.last < lowest_y || lowest_y == 0)
lowest_x = my_warpable_coords.first if (my_warpable_coords.first < lowest_x || lowest_x.zero? )
lowest_y = my_warpable_coords.last if (my_warpable_coords.last < lowest_y || lowest_y.zero? )
end
[lowest_x,lowest_y,warpable_coords]
end