From 4b0d59deff5a0bde2d16eb09c55e314512ad8cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lax=20de=20Carvalho=20Alves?= Date: Sat, 1 Jun 2019 12:30:56 -0300 Subject: [PATCH] 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 --- .codeclimate.yml | 1 + .rubocop.yml | 79 ++ .rubocop_shopify_styleguide.yml | 1090 +++++++++++++++++++++ .rubocop_todo.yml | 142 +++ Gemfile | 1 + Gemfile.lock | 20 +- app/controllers/annotations_controller.rb | 20 +- app/controllers/application_controller.rb | 5 +- app/controllers/export_controller.rb | 28 +- app/controllers/feeds_controller.rb | 10 +- app/controllers/images_controller.rb | 8 +- app/controllers/maps_controller.rb | 12 +- app/controllers/sessions_controller.rb | 48 +- app/controllers/tags_controller.rb | 2 +- app/controllers/users_controller.rb | 1 - app/helpers/application_helper.rb | 35 +- app/helpers/users_helper.rb | 90 ++ app/mailers/comment_mailer.rb | 7 +- app/models/annotation.rb | 24 +- app/models/comment.rb | 3 +- app/models/export.rb | 20 +- app/models/map.rb | 174 ++-- app/models/tag.rb | 9 +- app/models/user.rb | 22 +- app/models/warpable.rb | 144 +-- app/models/way.rb | 4 +- app/views/maps/_exports.html.erb | 2 +- config.ru | 2 +- lib/exporter.rb | 4 +- 29 files changed, 1709 insertions(+), 298 deletions(-) create mode 100644 .rubocop.yml create mode 100644 .rubocop_shopify_styleguide.yml create mode 100644 .rubocop_todo.yml create mode 100644 app/helpers/users_helper.rb diff --git a/.codeclimate.yml b/.codeclimate.yml index 5478188b7..4c1449c23 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -2,6 +2,7 @@ version: 2 plugins: rubocop: enabled: true + channel: rubocop-0-70 brakeman: enabled: true bundler-audit: diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 000000000..709769f4d --- /dev/null +++ b/.rubocop.yml @@ -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 diff --git a/.rubocop_shopify_styleguide.yml b/.rubocop_shopify_styleguide.yml new file mode 100644 index 000000000..8c9f268a0 --- /dev/null +++ b/.rubocop_shopify_styleguide.yml @@ -0,0 +1,1090 @@ +# http://shopify.github.io/ruby-style-guide/rubocop.yml +# + +Layout/AccessModifierIndentation: + EnforcedStyle: indent + SupportedStyles: + - outdent + - indent + IndentationWidth: + +Style/Alias: + EnforcedStyle: prefer_alias_method + SupportedStyles: + - prefer_alias + - prefer_alias_method + +Layout/AlignHash: + EnforcedHashRocketStyle: key + EnforcedColonStyle: key + EnforcedLastArgumentHashStyle: ignore_implicit + SupportedLastArgumentHashStyles: + - always_inspect + - always_ignore + - ignore_implicit + - ignore_explicit + +Layout/AlignParameters: + EnforcedStyle: with_fixed_indentation + SupportedStyles: + - with_first_parameter + - with_fixed_indentation + IndentationWidth: + +Style/AndOr: + EnforcedStyle: always + SupportedStyles: + - always + - conditionals + +Style/BarePercentLiterals: + EnforcedStyle: bare_percent + SupportedStyles: + - percent_q + - bare_percent + +Style/BlockDelimiters: + EnforcedStyle: line_count_based + SupportedStyles: + - line_count_based + - semantic + - braces_for_chaining + ProceduralMethods: + - benchmark + - bm + - bmbm + - create + - each_with_object + - measure + - new + - realtime + - tap + - with_object + FunctionalMethods: + - let + - let! + - subject + - watch + IgnoredMethods: + - lambda + - proc + - it + +Style/BracesAroundHashParameters: + EnforcedStyle: no_braces + SupportedStyles: + - braces + - no_braces + - context_dependent + +Layout/CaseIndentation: + EnforcedStyle: end + SupportedStyles: + - case + - end + IndentOneStep: false + IndentationWidth: + +Style/ClassAndModuleChildren: + EnforcedStyle: nested + SupportedStyles: + - nested + - compact + +Style/ClassCheck: + EnforcedStyle: is_a? + SupportedStyles: + - is_a? + - kind_of? + +Style/CommandLiteral: + EnforcedStyle: backticks + SupportedStyles: + - backticks + - percent_x + - mixed + AllowInnerBackticks: false + +Style/ConditionalAssignment: + EnforcedStyle: assign_to_condition + SupportedStyles: + - assign_to_condition + - assign_inside_condition + SingleLineConditionsOnly: true + +Layout/DotPosition: + EnforcedStyle: leading + SupportedStyles: + - leading + - trailing + +Style/EmptyElse: + EnforcedStyle: both + SupportedStyles: + - empty + - nil + - both + +Layout/EmptyLineBetweenDefs: + AllowAdjacentOneLineDefs: false + +Layout/EmptyLinesAroundBlockBody: + EnforcedStyle: no_empty_lines + SupportedStyles: + - empty_lines + - no_empty_lines + +Layout/EmptyLinesAroundClassBody: + EnforcedStyle: no_empty_lines + SupportedStyles: + - empty_lines + - empty_lines_except_namespace + - no_empty_lines + +Layout/EmptyLinesAroundModuleBody: + EnforcedStyle: no_empty_lines + SupportedStyles: + - empty_lines + - empty_lines_except_namespace + - no_empty_lines + +Layout/ExtraSpacing: + AllowForAlignment: true + ForceEqualSignAlignment: false + +Naming/FileName: + Exclude: [] + ExpectMatchingDefinition: false + Regex: + IgnoreExecutableScripts: true + +Layout/IndentFirstArgument: + EnforcedStyle: consistent + SupportedStyles: + - consistent + - special_for_inner_method_call + - special_for_inner_method_call_in_parentheses + IndentationWidth: + +Style/For: + EnforcedStyle: each + SupportedStyles: + - for + - each + +Style/FormatString: + EnforcedStyle: format + SupportedStyles: + - format + - sprintf + - percent + +Style/FrozenStringLiteralComment: + Details: >- + Add `# frozen_string_literal: true` to the top of the file. Frozen string + literals will become the default in a future Ruby version, and we want to + make sure we're ready. + SupportedStyles: + - when_needed + - always + - never + +Style/HashSyntax: + EnforcedStyle: ruby19 + SupportedStyles: + - ruby19 + - hash_rockets + - no_mixed_keys + - ruby19_no_mixed_keys + UseHashRocketsWithSymbolValues: false + PreferHashRocketsForNonAlnumEndingSymbols: false + +Layout/IndentationConsistency: + EnforcedStyle: normal + SupportedStyles: + - normal + - rails + +Layout/IndentationWidth: + Width: 2 + +Layout/IndentFirstArrayElement: + EnforcedStyle: consistent + SupportedStyles: + - special_inside_parentheses + - consistent + - align_brackets + IndentationWidth: + +Layout/IndentAssignment: + IndentationWidth: + +Layout/IndentFirstHashElement: + EnforcedStyle: consistent + SupportedStyles: + - special_inside_parentheses + - consistent + - align_braces + IndentationWidth: + +Style/LambdaCall: + EnforcedStyle: call + SupportedStyles: + - call + - braces + +Style/Next: + EnforcedStyle: skip_modifier_ifs + MinBodyLength: 3 + SupportedStyles: + - skip_modifier_ifs + - always + +Style/NonNilCheck: + IncludeSemanticChanges: false + +Style/MethodDefParentheses: + EnforcedStyle: require_parentheses + SupportedStyles: + - require_parentheses + - require_no_parentheses + - require_no_parentheses_except_multiline + +Naming/MethodName: + EnforcedStyle: snake_case + SupportedStyles: + - snake_case + - camelCase + +Layout/MultilineArrayBraceLayout: + EnforcedStyle: symmetrical + SupportedStyles: + - symmetrical + - new_line + - same_line + +Layout/MultilineHashBraceLayout: + EnforcedStyle: symmetrical + SupportedStyles: + - symmetrical + - new_line + - same_line + +Layout/MultilineMethodCallBraceLayout: + EnforcedStyle: symmetrical + SupportedStyles: + - symmetrical + - new_line + - same_line + +Layout/MultilineMethodCallIndentation: + EnforcedStyle: indented + SupportedStyles: + - aligned + - indented + - indented_relative_to_receiver + IndentationWidth: 2 + +Layout/MultilineMethodDefinitionBraceLayout: + EnforcedStyle: symmetrical + SupportedStyles: + - symmetrical + - new_line + - same_line + +Style/NumericLiteralPrefix: + EnforcedOctalStyle: zero_only + SupportedOctalStyles: + - zero_with_o + - zero_only + +Style/ParenthesesAroundCondition: + AllowSafeAssignment: true + +Style/PercentLiteralDelimiters: + PreferredDelimiters: + '%': '()' + '%i': '()' + '%q': '()' + '%Q': '()' + '%r': '{}' + '%s': '()' + '%w': '()' + '%W': '()' + '%x': '()' + +Style/PercentQLiterals: + EnforcedStyle: lower_case_q + SupportedStyles: + - lower_case_q + - upper_case_q + +Naming/PredicateName: + NamePrefix: + - is_ + NamePrefixBlacklist: + - is_ + NameWhitelist: + - is_a? + Exclude: + - 'spec/**/*' + +Style/PreferredHashMethods: + EnforcedStyle: short + SupportedStyles: + - short + - verbose + +Style/RaiseArgs: + EnforcedStyle: exploded + SupportedStyles: + - compact + - exploded + +Style/RedundantReturn: + AllowMultipleReturnValues: false + +Style/RegexpLiteral: + EnforcedStyle: slashes + SupportedStyles: + - slashes + - percent_r + - mixed + AllowInnerSlashes: false + +Style/SafeNavigation: + ConvertCodeThatCanStartToReturnNil: false + Enabled: true + +Lint/SafeNavigationChain: + Enabled: true + +Style/Semicolon: + AllowAsExpressionSeparator: false + +Style/SignalException: + EnforcedStyle: only_raise + SupportedStyles: + - only_raise + - only_fail + - semantic + +Style/SingleLineMethods: + AllowIfMethodIsEmpty: true + +Layout/SpaceBeforeFirstArg: + AllowForAlignment: true + +Style/SpecialGlobalVars: + EnforcedStyle: use_english_names + SupportedStyles: + - use_perl_names + - use_english_names + +Style/StabbyLambdaParentheses: + EnforcedStyle: require_parentheses + SupportedStyles: + - require_parentheses + - require_no_parentheses + +Style/StringLiteralsInInterpolation: + EnforcedStyle: single_quotes + SupportedStyles: + - single_quotes + - double_quotes + +Layout/SpaceAroundBlockParameters: + EnforcedStyleInsidePipes: no_space + SupportedStylesInsidePipes: + - space + - no_space + +Layout/SpaceAroundEqualsInParameterDefault: + EnforcedStyle: space + SupportedStyles: + - space + - no_space + +Layout/SpaceAroundOperators: + AllowForAlignment: true + +Layout/SpaceBeforeBlockBraces: + EnforcedStyle: space + EnforcedStyleForEmptyBraces: space + SupportedStyles: + - space + - no_space + +Layout/SpaceInsideBlockBraces: + EnforcedStyle: space + SupportedStyles: + - space + - no_space + EnforcedStyleForEmptyBraces: no_space + SpaceBeforeBlockParameters: true + +Layout/SpaceInsideHashLiteralBraces: + EnforcedStyle: space + EnforcedStyleForEmptyBraces: no_space + SupportedStyles: + - space + - no_space + - compact + +Layout/SpaceInsideStringInterpolation: + EnforcedStyle: no_space + SupportedStyles: + - space + - no_space + +Style/SymbolProc: + IgnoredMethods: + - respond_to + - define_method + +Style/TernaryParentheses: + EnforcedStyle: require_no_parentheses + SupportedStyles: + - require_parentheses + - require_no_parentheses + AllowSafeAssignment: true + +Layout/TrailingBlankLines: + EnforcedStyle: final_newline + SupportedStyles: + - final_newline + - final_blank_line + +Style/TrivialAccessors: + ExactNameMatch: true + AllowPredicates: true + AllowDSLWriters: false + IgnoreClassMethods: false + Whitelist: + - to_ary + - to_a + - to_c + - to_enum + - to_h + - to_hash + - to_i + - to_int + - to_io + - to_open + - to_path + - to_proc + - to_r + - to_regexp + - to_str + - to_s + - to_sym + +Naming/VariableName: + EnforcedStyle: snake_case + SupportedStyles: + - snake_case + - camelCase + +Style/WhileUntilModifier: + Enabled: true + +Style/WordArray: + EnforcedStyle: percent + SupportedStyles: + - percent + - brackets + MinSize: 0 + WordRegex: !ruby/regexp /\A[\p{Word}\n\t]+\z/ + +Layout/BlockAlignment: + EnforcedStyleAlignWith: either + SupportedStylesAlignWith: + - either + - start_of_block + - start_of_line + +Layout/DefEndAlignment: + EnforcedStyleAlignWith: start_of_line + SupportedStylesAlignWith: + - start_of_line + - def + +Lint/InheritException: + EnforcedStyle: runtime_error + SupportedStyles: + - runtime_error + - standard_error + +Lint/UnusedBlockArgument: + IgnoreEmptyBlocks: true + AllowUnusedKeywordArguments: false + +Lint/UnusedMethodArgument: + AllowUnusedKeywordArguments: false + IgnoreEmptyMethods: true + +Performance/RedundantMerge: + MaxKeyValuePairs: 2 + +Rails/ActionFilter: + EnforcedStyle: action + SupportedStyles: + - action + - filter + Include: + - app/controllers/**/*.rb + +Rails/Date: + EnforcedStyle: flexible + SupportedStyles: + - strict + - flexible + +Rails/DynamicFindBy: + Whitelist: + - find_by_sql + +Rails/Exit: + Include: + - app/**/*.rb + - config/**/*.rb + - lib/**/*.rb + Exclude: + - 'lib/**/*.rake' + +Rails/FindBy: + Include: + - app/models/**/*.rb + +Rails/FindEach: + Include: + - app/models/**/*.rb + +Rails/HasAndBelongsToMany: + Include: + - app/models/**/*.rb + +Rails/NotNullColumn: + Include: + - db/migrate/*.rb + +Rails/Output: + Include: + - app/**/*.rb + - config/**/*.rb + - db/**/*.rb + - lib/**/*.rb + +Rails/ReadWriteAttribute: + Include: + - app/models/**/*.rb + +Rails/RequestReferer: + EnforcedStyle: referer + SupportedStyles: + - referer + - referrer + +Rails/SafeNavigation: + ConvertTry: false + +Rails/ScopeArgs: + Include: + - app/models/**/*.rb + +Rails/TimeZone: + EnforcedStyle: flexible + SupportedStyles: + - strict + - flexible + +Rails/UniqBeforePluck: + EnforcedStyle: conservative + SupportedStyles: + - conservative + - aggressive + +Rails/Validation: + Include: + - app/models/**/*.rb + +Naming/AccessorMethodName: + Enabled: true + +Layout/AlignArray: + Enabled: true + +Style/ArrayJoin: + Enabled: true + +Naming/AsciiIdentifiers: + Enabled: true + +Style/Attr: + Enabled: true + +Style/BeginBlock: + Enabled: true + +Style/BlockComments: + Enabled: true + +Layout/BlockEndNewline: + Enabled: true + +Style/CaseEquality: + Enabled: true + +Style/CharacterLiteral: + Enabled: true + +Naming/ClassAndModuleCamelCase: + Enabled: true + +Style/ClassMethods: + Enabled: true + +Style/ClassVars: + Enabled: true + +Layout/ClosingParenthesisIndentation: + Enabled: true + +Style/ColonMethodCall: + Enabled: true + +Layout/CommentIndentation: + Enabled: true + +Naming/ConstantName: + Enabled: true + +Style/DefWithParentheses: + Enabled: true + +Style/EachForSimpleLoop: + Enabled: true + +Style/EachWithObject: + Enabled: true + +Layout/ElseAlignment: + Enabled: true + +Style/EmptyCaseCondition: + Enabled: true + +Layout/EmptyLines: + Enabled: true + +Layout/EmptyLinesAroundAccessModifier: + Enabled: true + +Layout/EmptyLinesAroundMethodBody: + Enabled: true + +Style/EmptyLiteral: + Enabled: true + +Style/EndBlock: + Enabled: true + +Layout/EndOfLine: + Enabled: true + +Style/EvenOdd: + Enabled: true + +Layout/InitialIndentation: + Enabled: true + +Lint/FlipFlop: + Enabled: true + +Style/IfInsideElse: + Enabled: true + +Style/IfUnlessModifierOfIfUnless: + Enabled: true + +Style/IfWithSemicolon: + Enabled: true + +Style/IdenticalConditionalBranches: + Enabled: true + +Style/InfiniteLoop: + Enabled: true + +Layout/LeadingCommentSpace: + Enabled: true + +Style/LineEndConcatenation: + Enabled: true + +Style/MethodCallWithoutArgsParentheses: + Enabled: true + +Style/MultilineBlockChain: + Enabled: true + +Layout/MultilineBlockLayout: + Enabled: true + +Style/MultilineIfThen: + Enabled: true + +Style/MultilineMemoization: + Enabled: true + +Style/MultilineTernaryOperator: + Enabled: true + +Style/NegatedIf: + Enabled: true + +Style/NegatedWhile: + Enabled: true + +Style/NestedModifier: + Enabled: true + +Style/NestedParenthesizedCalls: + Enabled: true + +Style/NestedTernaryOperator: + Enabled: true + +Style/NilComparison: + Enabled: true + +Style/Not: + Enabled: true + +Style/OneLineConditional: + Enabled: true + +Naming/BinaryOperatorParameterName: + Enabled: true + +Style/OptionalArguments: + Enabled: true + +Style/ParallelAssignment: + Enabled: true + +Style/PerlBackrefs: + Enabled: true + +Style/Proc: + Enabled: true + +Style/RedundantBegin: + Enabled: true + +Style/RedundantException: + Enabled: true + +Style/RedundantFreeze: + Enabled: true + +Style/RedundantParentheses: + Enabled: true + +Style/RedundantSelf: + Enabled: true + +Layout/RescueEnsureAlignment: + Enabled: true + +Style/RescueModifier: + Enabled: true + +Style/SelfAssignment: + Enabled: true + +Layout/SpaceAfterColon: + Enabled: true + +Layout/SpaceAfterComma: + Enabled: true + +Layout/SpaceAfterMethodName: + Enabled: true + +Layout/SpaceAfterNot: + Enabled: true + +Layout/SpaceAfterSemicolon: + Enabled: true + +Layout/SpaceBeforeComma: + Enabled: true + +Layout/SpaceBeforeComment: + Enabled: true + +Layout/SpaceBeforeSemicolon: + Enabled: true + +Layout/SpaceAroundKeyword: + Enabled: true + +Layout/SpaceInsideArrayPercentLiteral: + Enabled: true + +Layout/SpaceInsidePercentLiteralDelimiters: + Enabled: true + +Layout/SpaceInsideArrayLiteralBrackets: + Enabled: true + +Layout/SpaceInsideParens: + Enabled: true + +Layout/SpaceInsideRangeLiteral: + Enabled: true + +Style/SymbolLiteral: + Enabled: true + +Layout/Tab: + Enabled: true + +Layout/TrailingWhitespace: + Enabled: true + +Style/UnlessElse: + Enabled: true + +Style/UnneededCapitalW: + Enabled: true + +Style/UnneededInterpolation: + Enabled: true + +Style/UnneededPercentQ: + Enabled: true + +Style/VariableInterpolation: + Enabled: true + +Style/WhenThen: + Enabled: true + +Style/WhileUntilDo: + Enabled: true + +Style/ZeroLengthPredicate: + Enabled: true + +Layout/IndentHeredoc: + EnforcedStyle: squiggly + +Lint/AmbiguousOperator: + Enabled: true + +Lint/AmbiguousRegexpLiteral: + Enabled: true + +Lint/CircularArgumentReference: + Enabled: true + +Layout/ConditionPosition: + Enabled: true + +Lint/Debugger: + Enabled: true + +Lint/DeprecatedClassMethods: + Enabled: true + +Lint/DuplicateMethods: + Enabled: true + +Lint/DuplicatedKey: + Enabled: true + +Lint/EachWithObjectArgument: + Enabled: true + +Lint/ElseLayout: + Enabled: true + +Lint/EmptyEnsure: + Enabled: true + +Lint/EmptyInterpolation: + Enabled: true + +Lint/EndInMethod: + Enabled: true + +Lint/EnsureReturn: + Enabled: true + +Lint/FloatOutOfRange: + Enabled: true + +Lint/FormatParameterMismatch: + Enabled: true + +Lint/HandleExceptions: + Enabled: true + +Lint/ImplicitStringConcatenation: + Description: Checks for adjacent string literals on the same line, which could + better be represented as a single string literal. + +Lint/IneffectiveAccessModifier: + Description: Checks for attempts to use `private` or `protected` to set the visibility + of a class method, which does not work. + +Lint/LiteralAsCondition: + Enabled: true + +Lint/LiteralInInterpolation: + Enabled: true + +Lint/Loop: + Description: Use Kernel#loop with break rather than begin/end/until or begin/end/while + for post-loop tests. + +Lint/NestedMethodDefinition: + Enabled: true + +Lint/NextWithoutAccumulator: + Description: Do not omit the accumulator when calling `next` in a `reduce`/`inject` + block. + +Lint/NonLocalExitFromIterator: + Enabled: true + +Lint/ParenthesesAsGroupedExpression: + Enabled: true + +Lint/PercentStringArray: + Enabled: true + +Lint/PercentSymbolArray: + Enabled: true + +Lint/RandOne: + Description: Checks for `rand(1)` calls. Such calls always return `0` and most + likely a mistake. + +Lint/RequireParentheses: + Enabled: true + +Lint/RescueException: + Enabled: true + +Lint/ShadowedException: + Enabled: true + +Lint/ShadowingOuterLocalVariable: + Enabled: true + +Lint/StringConversionInInterpolation: + Enabled: true + +Lint/UnderscorePrefixedVariableName: + Enabled: true + +Lint/UnifiedInteger: + Enabled: true + +Lint/UnneededSplatExpansion: + Enabled: true + +Lint/UnreachableCode: + Enabled: true + +Lint/UselessAccessModifier: + ContextCreatingMethods: [] + +Lint/UselessComparison: + Enabled: true + +Lint/UselessElseWithoutRescue: + Enabled: true + +Lint/UselessSetterCall: + Enabled: true + +Lint/Void: + Enabled: true + +Performance/CaseWhenSplat: + Enabled: true + +Performance/Count: + SafeMode: true + +Performance/Detect: + SafeMode: true + +Performance/DoubleStartEndWith: + Enabled: true + +Performance/EndWith: + Enabled: true + +Performance/FixedSize: + Enabled: true + +Performance/FlatMap: + EnabledForFlattenWithoutParams: false + +Performance/RangeInclude: + Enabled: true + +Performance/RedundantBlockCall: + Enabled: true + +Performance/RedundantMatch: + Enabled: true + +Style/RedundantSortBy: + Enabled: true + +Performance/ReverseEach: + Enabled: true + +Style/Sample: + Enabled: true + +Performance/Size: + Enabled: true + +Performance/CompareWithBlock: + Enabled: true + +Performance/StartWith: + Enabled: true + +Performance/StringReplacement: + Enabled: true + +Rails/DelegateAllowBlank: + Enabled: true + +Rails/HttpPositionalArguments: + Include: + - spec/**/* + - test/**/* + +Rails/OutputSafety: + Enabled: true + +Rails/PluralizationGrammar: + Enabled: true + +Security/Eval: + Enabled: true + +Security/JSONLoad: + Enabled: true + +Style/ModuleFunction: + EnforcedStyle: extend_self diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 000000000..a7ab4486f --- /dev/null +++ b/.rubocop_todo.yml @@ -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' diff --git a/Gemfile b/Gemfile index 5b72a59a2..92051d954 100644 --- a/Gemfile +++ b/Gemfile @@ -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' diff --git a/Gemfile.lock b/Gemfile.lock index 494d0e44d..d781a44a8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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 diff --git a/app/controllers/annotations_controller.rb b/app/controllers/annotations_controller.rb index b4f99581a..3435ce4c0 100644 --- a/app/controllers/annotations_controller.rb +++ b/app/controllers/annotations_controller.rb @@ -12,7 +12,7 @@ def create 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 @@ def create ) @annotation.user_id = current_user.id if logged_in? redirect_to map_annotation_url(@map, @annotation) if @annotation.save - } + end end end @@ -33,14 +33,14 @@ def show def update @annotation = Annotation.find params[:id] geojson = params[:annotation] - 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]) - render file: 'annotations/update.json.erb', - content_type: 'application/json' - end + 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]) + render file: 'annotations/update.json.erb', + content_type: 'application/json' end def destroy diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index edbfc406e..06862c217 100755 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -14,7 +14,7 @@ def current_user if user_id begin @user = User.find(user_id) - rescue + rescue StandardError @user = nil end else @@ -41,13 +41,14 @@ def logged_in? 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 diff --git a/app/controllers/export_controller.rb b/app/controllers/export_controller.rb index 9638334ab..2b3c98470 100644 --- a/app/controllers/export_controller.rb +++ b/app/controllers/export_controller.rb @@ -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,19 +51,19 @@ def cancel def progress map = Map.find params[:id] export = map.export - if export.present? - if export.status == 'complete' - output = 'complete' - elsif export.status == 'none' - output = 'export not running' - elsif export.status == 'failed' - output = 'export failed' - else - output = export.status - end - else - output = 'export has not been run' - end + output = if export.present? + if export.status == 'complete' + 'complete' + elsif export.status == 'none' + 'export not running' + elsif export.status == 'failed' + 'export failed' + else + export.status + end + else + 'export has not been run' + end render text: output, layout: false end diff --git a/app/controllers/feeds_controller.rb b/app/controllers/feeds_controller.rb index 6575f55e5..3405ea31d 100644 --- a/app/controllers/feeds_controller.rb +++ b/app/controllers/feeds_controller.rb @@ -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' @@ -24,9 +24,9 @@ def license def author @maps = Map.find_all_by_author(params[:id], - order: 'id DESC', - conditions: { archived: false, password: '' }, - joins: :warpables, group: 'maps.id') + order: 'id DESC', + conditions: { archived: false, password: '' }, + joins: :warpables, group: 'maps.id') images = [] @maps.each do |map| images += map.warpables diff --git a/app/controllers/images_controller.rb b/app/controllers/images_controller.rb index ef00821bf..2f670da0f 100644 --- a/app/controllers/images_controller.rb +++ b/app/controllers/images_controller.rb @@ -1,9 +1,9 @@ require 'open-uri' 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] + 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 @@ -21,7 +21,6 @@ def fetch end end - # rubocop:disable LineLength # assign attributes directly after rails update def create @warpable = Warpable.new @@ -41,7 +40,6 @@ def create end end end - # rubocop:enable LineLength # mapknitter.org/import//?url=http://myurl.com/image.jpg def import diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index 40e6b7077..51258908e 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -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' @@ -177,7 +176,7 @@ def featured render 'maps/index', layout: 'application' end - def search + def search data = params[:q] query = params[:q].gsub(/\s+/, '') @@ -193,13 +192,12 @@ def search format.html { render 'maps/index', layout: 'application' } format.json { render json: @maps } end - end + end end - + private def find_map @map = Map.find(params[:id]) end end -# rubocop:enable LineLength diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index ca1213845..65a0f181a 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -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,29 +19,29 @@ def create 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] - # provider based authentication - url = openid_url + "/" + params[:subaction] - else - # form based authentication - url = openid_url - end + url = if params[:subaction] + # provider based authentication + openid_url + "/" + params[:subaction] + else + # form based authentication + openid_url + end end else - if params[:subaction] - # provider based authentication - url = @@openid_url_base + openid_url + @@openid_url_suffix + "/" + params[:subaction] - else - # form based authentication - url = @@openid_url_base + openid_url + @@openid_url_suffix - end + url = if params[:subaction] + # provider based authentication + @openid_url_base + openid_url + @openid_url_suffix + "/" + params[:subaction] + else + # form based authentication + @openid_url_base + openid_url + @openid_url_suffix + end end openid_authentication(url, back_to) end @@ -66,8 +66,8 @@ def logout protected 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| + # puts openid_url + 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,18 +77,18 @@ def openid_authentication(openid_url, back_to) 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'] @user.identity_url = identity_url hash = registration['fullname'].split(':') - @user.role = hash[1].split('=')[1] + @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 diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index e3d09dc0c..f6ad5ab3d 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -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] diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 38734087b..56d9379e6 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -27,5 +27,4 @@ def sort_column def sort_direction params[:direction] || 'desc' end - end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7f03be18a..3bad0e562 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,11 +1,10 @@ module ApplicationHelper - def current_user - user_id = session[:user_id] + user_id = session[:user_id] if user_id begin @user = User.find(user_id) - rescue + rescue StandardError @user = nil end else @@ -15,19 +14,19 @@ def current_user # add this to app/helpers/application_helper.rb # http://www.emersonlackey.com/article/rails3-error-messages-for-replacemen - def errors_for(object, message=nil) + def errors_for(object, message = nil) html = "" unless object.nil? || object.errors.blank? html << "
\n" - if message.blank? - if object.new_record? - html << "\t\t
There was a problem creating the #{object.class.name.humanize.downcase}
\n" - else - html << "\t\t
There was a problem updating the #{object.class.name.humanize.downcase}
\n" - end - else - html << "
#{message}
" - end + html << if message.blank? + if object.new_record? + "\t\t
There was a problem creating the #{object.class.name.humanize.downcase}
\n" + else + "\t\t
There was a problem updating the #{object.class.name.humanize.downcase}
\n" + end + else + "
#{message}
" + end html << "\t\t
    \n" object.errors.full_messages.each do |error| html << "\t\t\t
  • #{error}
  • \n" @@ -36,16 +35,15 @@ def errors_for(object, message=nil) html << "\t
\n" end html - end + end # polyfill for jquery-ujs in rails 2.x # see https://github.com/rails/jquery-ujs/wiki/Manual-installing-and-Rails-2 def csrf_meta_tags if protect_against_forgery? - out = %(\n) - out << %() - out % [ Rack::Utils.escape_html(request_forgery_protection_token), - Rack::Utils.escape_html(form_authenticity_token) ] + out = %(\n) # rubocop:disable Style/FormatStringToken + out << %() # 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 @@ def sortable(column, title = nil) direction = column == sort_column && sort_direction == 'asc' ? 'desc' : 'asc' link_to title, sort: column, direction: direction end - end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 000000000..346881184 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -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 + # # => barmy + # + # # 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 + # # => Cyril Fotheringay-Phipps: + # + # link_to_user @user, :content_text => 'Your user page' + # # => Your user page + # + 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 + # # => 169.69.69.69 + # + # link_to_login_with_IP :content_text => 'not signed in' + # # => not signed in + # + 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 diff --git a/app/mailers/comment_mailer.rb b/app/mailers/comment_mailer.rb index 7ae911cec..cb369928a 100644 --- a/app/mailers/comment_mailer.rb +++ b/app/mailers/comment_mailer.rb @@ -1,11 +1,10 @@ class CommentMailer < ActionMailer::Base default from: "do-not-reply@mapknitter.org" - # CommentMailer.notify_of_comment(user,self).deliver - def notify(user,comment) + # CommentMailer.notify_of_comment(user,self).deliver + 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 diff --git a/app/models/annotation.rb b/app/models/annotation.rb index c2ec90bbb..bfa3ce87c 100644 --- a/app/models/annotation.rb +++ b/app/models/annotation.rb @@ -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 - when 'polyline' then - geometry_type = 'LineString' - when 'polygon' then - geometry_type = 'Polygon' - when 'rectangle' then - geometry_type = 'Polygon' - else - geometry_type = 'Point' - end + geometry_type = case annotation_type + when 'polyline' then + 'LineString' + when 'polygon' then + 'Polygon' + when 'rectangle' then + 'Polygon' + else + 'Point' + end - return geometry_type + geometry_type end end diff --git a/app/models/comment.rb b/app/models/comment.rb index e5f594428..8ac15586e 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -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 diff --git a/app/models/export.rb b/app/models/export.rb index ebeaa3a33..94c96d17b 100644 --- a/app/models/export.rb +++ b/app/models/export.rb @@ -6,25 +6,25 @@ 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 - sum/e.length + if !e.empty? + sum / e.length else 0 end 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,21 +42,21 @@ def self.histogram_cm_per_pixel_in_tens 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| - hist[export.cm_per_pixel/10.to_i] += 1 + hist[export.cm_per_pixel / 10.to_i] += 1 end hist 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 diff --git a/app/models/map.rb b/app/models/map.rb index 400211d84..20878f3d6 100755 --- a/app/models/map.rb +++ b/app/models/map.rb @@ -1,23 +1,23 @@ 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 + attr_accessible :author, :name, :slug, :lat, :lon, + :location, :description, :zoom, :license attr_accessor :image_urls validates :name, :slug, :author, :lat, :lon, presence: true - - validates :slug, format: { - with: /^[\w-]*$/, - message: "must only include permitted URL safe character types: - alphanumerics, dashes, and underscores. It will be in your map's - URL path (i.e., https://mapknitter.org/maps/your-map-name)." + + validates :slug, format: { + with: /^[\w-]*$/, + message: "must only include permitted URL safe character types: + alphanumerics, dashes, and underscores. It will be in your map's + URL path (i.e., https://mapknitter.org/maps/your-map-name)." }, uniqueness: true, on: :create - - validates :location, presence: { - message: ' cannot be found. + + validates :location, presence: { + message: ' cannot be found. Try entering a latitude and longitude if this problem persists.' } # validates :tile_url, format { with: @@ -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,42 +51,41 @@ def public_filenames 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) - Map.where(['lat > ? AND lat < ? AND lon > ? AND lon < ?', + Map.where(['lat > ? AND lat < ? AND lon > ? AND lon < ?', minlat, maxlat, minlon, maxlon]) 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,26 +95,26 @@ def self.authors(limit = 50) .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 ? + .where(['author LIKE ? OR name LIKE ? OR location LIKE ? OR description LIKE ?', - "%#{q}%", "%#{q}%", "%#{q}%", "%#{q}%"]) + "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%"]) end def self.featured Map.joins(:warpables) .select('maps.*, count(maps.id) as image_count') .group('warpables.map_id') - .order('image_count DESC') + .order('image_count DESC') end def self.new_maps Map.find( - :all, - order: 'created_at DESC', - limit: 12, + :all, + order: 'created_at DESC', + limit: 12, conditions: ['password = "" AND archived = "false"'] ) end @@ -130,7 +129,7 @@ def self.map def self.featured_authors maps = Map.active.has_user - + author_counts = maps.group('author') .select('user_id, author, count(1) as maps_count') .order('maps_count DESC') @@ -144,17 +143,17 @@ def self.featured_authors def self.maps_nearby(lat:, lon:, dist:) Map.active .where(['lat>? AND lat? AND lon 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, + :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,25 +180,25 @@ def average_scale # determine optimal zoom level puts '> calculating scale' pxperms = [] - self.placed_warpables.each do |warpable| - pxperms << 100.00/warpable.cm_per_pixel if warpable.placed? + 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 + average = (pxperms.inject { |sum, n| sum + n }) / pxperms.length average end def best_cm_per_pixel - hist = self.images_histogram + hist = images_histogram scores = [] - (0..(hist.length-1)).each do |i| + (0..(hist.length - 1)).each do |i| scores[i] = 0 - scores[i] += hist[i-3] if i > 3 - scores[i] += hist[i-2] if i > 2 - scores[i] += hist[i-1] if i > 1 + scores[i] += hist[i - 3] if i > 3 + scores[i] += hist[i - 2] if i > 2 + scores[i] += hist[i - 1] if i > 1 scores[i] += hist[i] - scores[i] += hist[i+1] if i < hist.length - 2 - scores[i] += hist[i+2] if i < hist.length - 3 - scores[i] += hist[i+3] if i < hist.length - 4 + scores[i] += hist[i + 1] if i < hist.length - 2 + scores[i] += hist[i + 2] if i < hist.length - 3 + scores[i] += hist[i + 3] if i < hist.length - 4 end highest = 0 scores.each_with_index { |s, i| highest = i if s > scores[highest] } @@ -206,17 +206,17 @@ def best_cm_per_pixel 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 + total_sum = (scales.inject { |sum, n| sum + n }) if scales + return total_sum / count if total_sum else 0 end @@ -225,13 +225,13 @@ def average_cm_per_pixel # 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 + (0..hist.length - 1).each do |bin| + hist[bin] = 0 if hist[bin].nil? end hist end @@ -239,16 +239,16 @@ def images_histogram # 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 - res = (warpable.cm_per_pixel/(0.001+binsize)).to_i - hist[res] = 0 if hist[res] == nil - hist[res] += 1 - end + next if res.nil? + + res = (warpable.cm_per_pixel / (0.001 + binsize)).to_i + 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 + (0..hist.length - 1).each do |bin| + hist[bin] = 0 if hist[bin].nil? end hist end @@ -261,38 +261,36 @@ def run_export(user, resolution) 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") - self.version = last.version + 1 - end + return unless Map.find_by_name(slug, order: "version DESC") + + self.version = last.version + 1 end def license_link - if self.license == "cc-by" - "Creative Commons Attribution 3.0 Unported License" - elsif self.license == "publicdomain" - "Public Domain" + if license == "cc-by" + "Creative Commons Attribution 3.0 Unported License" + elsif license == "publicdomain" + "Public Domain" 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 diff --git a/app/models/tag.rb b/app/models/tag.rb index 761815f86..3a699d727 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 25cc2d7ee..28050d3c2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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 @@ def email=(value) 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 diff --git a/app/models/warpable.rb b/app/models/warpable.rb index 41d4b91dd..a35fce0d1 100755 --- a/app/models/warpable.rb +++ b/app/models/warpable.rb @@ -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, - "delete_type" => "DELETE"} + { "name" => read_attribute(:image_filename), + "size" => read_attribute(:image_size), + "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"]} + { "name" => read_attribute(:image_filename), + "size" => read_attribute(:image_size), + "error" => errors["base"] } end after_save :save_dimensions @@ -44,72 +45,72 @@ def fup_error_json # 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 - else - geo = Paperclip::Geometry.from_file(Paperclip.io_adapters.for(self.image).path) # local filesystem version - end - - #Rails >= v3.1 only - self.update_column(:width, geo.width) - self.update_column(:height, geo.height) - #Rails >= v4.0 only - #self.update_columns(attributes) + geo = if Rails.env.production? + Paperclip::Geometry.from_file(Paperclip.io_adapters.for(image.url)) # s3 version + else + Paperclip::Geometry.from_file(Paperclip.io_adapters.for(image).path) # local filesystem version + end + + # Rails >= v3.1 only + 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.each_with_index do |node,index| - if index < nodes.length-1 - nextnode = nodes[index+1] - else - nextnode = nodes[0] - end - if index > 0 - last = nodes[index-1] - else - last = nodes[nodes.length-1] - end - scale = 20037508.34 + nodes = nodes_array + nodes.each_with_index do |node, index| + nextnode = if index < nodes.length - 1 + nodes[index + 1] + else + nodes[0] + end + last = if index.positive? + nodes[index - 1] + else + nodes[nodes.length - 1] + end + 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) - nodex = Cartagen.spherical_mercator_lon_to_x(node.lon,scale) - lasty = Cartagen.spherical_mercator_lat_to_y(last.lat,scale) - lastx = Cartagen.spherical_mercator_lon_to_x(last.lon,scale) - nexty = Cartagen.spherical_mercator_lat_to_y(nextnode.lat,scale) - nextx = Cartagen.spherical_mercator_lon_to_x(nextnode.lon,scale) - area += lastx*nodey-nodex*lasty+nodex*nexty-nextx*nodey + nodey = Cartagen.spherical_mercator_lat_to_y(node.lat, scale) + nodex = Cartagen.spherical_mercator_lon_to_x(node.lon, scale) + lasty = Cartagen.spherical_mercator_lat_to_y(last.lat, scale) + lastx = Cartagen.spherical_mercator_lon_to_x(last.lon, scale) + nexty = Cartagen.spherical_mercator_lat_to_y(nextnode.lat, scale) + nextx = Cartagen.spherical_mercator_lon_to_x(nextnode.lon, scale) + area += lastx * nodey - nodex * lasty + nodex * nexty - nextx * nodey end - (area/2).abs + (area / 2).abs end # 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 - 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 = 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) / 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 @@ def self.histogram_cm_per_pixel end def nodes_array - Node.find self.nodes.split(',') + Node.find nodes.split(',') end # allow uploads via URL @@ -132,8 +133,13 @@ def nodes_array 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 @@ def generate_perspectival_distort(pxperm, path) 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 diff --git a/app/models/way.rb b/app/models/way.rb index 4e8ba65bb..f92f1f1df 100644 --- a/app/models/way.rb +++ b/app/models/way.rb @@ -1,9 +1,9 @@ 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 - self.lon1,self.lat2,self.lon2,self.lat1 = bbox + self.lon1, self.lat2, self.lon2, self.lat1 = bbox end end diff --git a/app/views/maps/_exports.html.erb b/app/views/maps/_exports.html.erb index 77c33aaba..0d25aab41 100644 --- a/app/views/maps/_exports.html.erb +++ b/app/views/maps/_exports.html.erb @@ -1,4 +1,4 @@ -<% if @map.exports.length == 0 || @map.exports.first.status == 'none' %> +<% if @map.exports.length.zero? || @map.exports.first.status == 'none' %> <% else %> <% if !@map.exports.first.jpg && !@map.exports.first.geotiff && !@map.exports.first.tms && !@map.exports.first.zip %> diff --git a/config.ru b/config.ru index ee4a427b4..2b2ae190a 100644 --- a/config.ru +++ b/config.ru @@ -1,4 +1,4 @@ # This file is used by Rack-based servers to start the application. -require ::File.expand_path('../config/environment', __FILE__) +require ::File.expand_path('../config/environment', __FILE__) run Mapknitter::Application diff --git a/lib/exporter.rb b/lib/exporter.rb index b045d4a2f..bcae11dd1 100644 --- a/lib/exporter.rb +++ b/lib/exporter.rb @@ -231,8 +231,8 @@ def self.distort_warpables(scale, warpables, export, slug) 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