diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 00000000..95e3ba81 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.5 diff --git a/Gemfile b/Gemfile index 4d6d2421..7609b85a 100644 --- a/Gemfile +++ b/Gemfile @@ -56,16 +56,15 @@ group :development, :test do end group :test do - gem 'rails-controller-testing' - gem 'rails-dom-testing', '~> 2.0.0' - gem 'factory_bot_rails' - gem 'rspec-expectations' - gem 'database_cleaner' - gem 'mocha', :require => false - gem 'minitest-stub-const' - - gem 'simplecov' # get test coverage info on codeclimate gem 'codeclimate-test-reporter', '1.0.7', group: :test, require: nil + gem 'database_cleaner' + gem 'factory_bot_rails' + gem 'mocha', :require => false + gem 'minitest-stub-const' + gem 'rails-controller-testing' + gem 'rails-dom-testing', '~> 2.0.0' + gem 'rspec-expectations' + gem 'simplecov' end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1812b9ac..5b4e2407 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -10,7 +10,7 @@ class ApplicationController < ActionController::Base include Common helper_method :current_user, :prefs, :format_date - layout proc{ |controller| controller.mobile? ? "mobile" : "application" } + layout proc { |controller| controller.mobile? ? "mobile" : "application" } # exempt_from_layout /\.js\.erb$/ before_action :set_session_expiration @@ -27,7 +27,7 @@ class ApplicationController < ActionController::Base locale ||= prefs.locale unless current_user.nil? # otherwise, the locale of the currently logged in user takes over locale ||= request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first if request.env['HTTP_ACCEPT_LANGUAGE'] - if locale && I18n::available_locales.map(&:to_s).include?(locale.to_s) + if locale && I18n.available_locales.map(&:to_s).include?(locale.to_s) I18n.locale = locale else I18n.locale = I18n.default_locale @@ -39,7 +39,7 @@ class ApplicationController < ActionController::Base # If the method is called by the feed controller (which we don't have # under session control) or if we checked the box to keep logged in on # login don't set the session expiry time. - return if session.nil? || self.controller_name == 'feed' || session['noexpiry'] == "on" + return if session.nil? || controller_name == 'feed' || session['noexpiry'] == "on" # Get expiry time (allow ten seconds window for the case where we have # none) @@ -50,11 +50,11 @@ class ApplicationController < ActionController::Base reset_session else # Okay, you get another hour - session['expiry_time'] = now + (60*60) + session['expiry_time'] = now + (60 * 60) end end - def render_failure message, status = 404 + def render_failure(message, status = 404) render :body => message, :status => status end @@ -101,8 +101,8 @@ class ApplicationController < ActionController::Base def for_autocomplete(coll, substr) if substr # protect agains empty request - filtered = coll.find_all{ |item| item.name.downcase.include? substr.downcase } - json_elems = Array[*filtered.map{ |e| { :id => e.id.to_s, :value => e.name } }].to_json + filtered = coll.find_all { |item| item.name.downcase.include? substr.downcase } + json_elems = Array[*filtered.map { |e| { :id => e.id.to_s, :value => e.name } }].to_json return json_elems else return "" @@ -272,7 +272,7 @@ class ApplicationController < ActionController::Base def done_todos_for(object) object_name = object.class.name.downcase # context or project @source_view = "done" - eval("@#{object_name} = object") + eval("@#{object_name} = object", binding, __FILE__, __LINE__) @page_title = t("#{object_name.pluralize}.completed_tasks_title", "#{object_name}_name".to_sym => object.name) @done_today, @done_rest_of_week, @done_rest_of_month = DoneTodos.done_todos_for_container(object.todos) diff --git a/app/controllers/calendar_controller.rb b/app/controllers/calendar_controller.rb index 87f37ea5..55a8dd97 100644 --- a/app/controllers/calendar_controller.rb +++ b/app/controllers/calendar_controller.rb @@ -15,7 +15,7 @@ class CalendarController < ApplicationController format.html format.m { cookies[:mobile_url] = { :value => request.fullpath, :secure => SITE_CONFIG['secure_cookies'] } } format.ics { render :action => 'show', :layout => false, :content_type => Mime[:ics] } - format.xml { render :xml => @due_all.to_xml( *[todo_xml_params[0].merge({ :root => :todos })] ) } + format.xml { render :xml => @due_all.to_xml(*[todo_xml_params[0].merge({ :root => :todos })]) } end end end diff --git a/app/controllers/contexts_controller.rb b/app/controllers/contexts_controller.rb index 3121ac56..b1ff4c1b 100644 --- a/app/controllers/contexts_controller.rb +++ b/app/controllers/contexts_controller.rb @@ -98,7 +98,7 @@ class ContextsController < ApplicationController @context.attributes = context_params @saved = @context.save @state_saved = set_state_for_update(@new_state) - @saved = @saved && @state_saved + @saved &&= @state_saved if @saved @state_changed = (@original_context_state != @context.state) @@ -148,7 +148,7 @@ class ContextsController < ApplicationController # def order context_ids = params["container_context"] - @projects = current_user.contexts.update_positions( context_ids ) + @projects = current_user.contexts.update_positions(context_ids) head :ok rescue notify :error, $! diff --git a/app/controllers/data_controller.rb b/app/controllers/data_controller.rb index e0444fd8..16ed4fcc 100644 --- a/app/controllers/data_controller.rb +++ b/app/controllers/data_controller.rb @@ -5,8 +5,7 @@ class DataController < ApplicationController @page_title = "TRACKS::Export" end - def import - end + def import; end def csv_map if params[:file].blank? @@ -16,17 +15,17 @@ class DataController < ApplicationController @import_to = params[:import_to] begin - #get column headers and format as [['name', column_number]...] + # Get column headers and format as [['name', column_number]...] i = -1 - @headers = import_headers(params[:file].path).collect { |v| [v, i+=1] } - @headers.unshift ['',i] + @headers = import_headers(params[:file].path).collect { |v| [v, i += 1] } + @headers.unshift ['', i] rescue Exception => e flash[:error] = "Invalid CVS: could not read headers: #{e}" redirect_to :back return end - #save file for later + # Save file for later begin uploaded_file = params[:file] @filename = sanitize_filename(uploaded_file.original_filename) @@ -94,17 +93,17 @@ class DataController < ApplicationController all_tables['projects'] = current_user.projects.load todo_tag_ids = Tag.find_by_sql([ - "SELECT DISTINCT tags.id "+ - "FROM tags, taggings, todos "+ - "WHERE todos.user_id=? "+ - "AND tags.id = taggings.tag_id " + - "AND taggings.taggable_id = todos.id ", current_user.id]) + "SELECT DISTINCT tags.id + FROM tags, taggings, todos + WHERE todos.user_id = ? + AND tags.id = taggings.tag_id + AND taggings.taggable_id = todos.id", current_user.id]) rec_todo_tag_ids = Tag.find_by_sql([ - "SELECT DISTINCT tags.id "+ - "FROM tags, taggings, recurring_todos "+ - "WHERE recurring_todos.user_id=? "+ - "AND tags.id = taggings.tag_id " + - "AND taggings.taggable_id = recurring_todos.id ", current_user.id]) + "SELECT DISTINCT tags.id + FROM tags, taggings, recurring_todos + WHERE recurring_todos.user_id = ? + AND tags.id = taggings.tag_id + AND taggings.taggable_id = recurring_todos.id", current_user.id]) tags = Tag.where("id IN (?) OR id IN (?)", todo_tag_ids, rec_todo_tag_ids) taggings = Tagging.where("tag_id IN (?) OR tag_id IN(?)", todo_tag_ids, rec_todo_tag_ids) @@ -114,7 +113,8 @@ class DataController < ApplicationController all_tables['recurring_todos'] = current_user.recurring_todos.load result = all_tables.to_yaml - result.gsub!(/\n/, "\r\n") # TODO: general functionality for line endings + # TODO: general functionality for line endings + result.gsub!(/\n/, "\r\n") send_data(result, :filename => "tracks_backup.yml", :type => 'text/plain') end @@ -129,7 +129,7 @@ class DataController < ApplicationController csv << [todo.id, todo.context.name, todo.project_id.nil? ? "" : todo.project.name, todo.description, - todo.notes, todo.tags.collect{|t| t.name}.join(', '), + todo.notes, todo.tags.collect { |t| t.name }.join(', '), todo.created_at.to_formatted_s(:db), todo.due? ? todo.due.to_formatted_s(:db) : "", todo.completed_at? ? todo.completed_at.to_formatted_s(:db) : "", @@ -163,17 +163,17 @@ class DataController < ApplicationController def xml_export todo_tag_ids = Tag.find_by_sql([ - "SELECT DISTINCT tags.id "+ - "FROM tags, taggings, todos "+ - "WHERE todos.user_id=? "+ - "AND tags.id = taggings.tag_id " + - "AND taggings.taggable_id = todos.id ", current_user.id]) + "SELECT DISTINCT tags.id + FROM tags, taggings, todos + WHERE todos.user_id = ? + AND tags.id = taggings.tag_id + AND taggings.taggable_id = todos.id", current_user.id]) rec_todo_tag_ids = Tag.find_by_sql([ - "SELECT DISTINCT tags.id "+ - "FROM tags, taggings, recurring_todos "+ - "WHERE recurring_todos.user_id=? "+ - "AND tags.id = taggings.tag_id " + - "AND taggings.taggable_id = recurring_todos.id ", current_user.id]) + "SELECT DISTINCT tags.id + FROM tags, taggings, recurring_todos + WHERE recurring_todos.user_id = ? + AND tags.id = taggings.tag_id + AND taggings.taggable_id = recurring_todos.id", current_user.id]) tags = Tag.where("id IN (?) OR id IN (?)", todo_tag_ids, rec_todo_tag_ids) taggings = Tagging.where("tag_id IN (?) OR tag_id IN(?)", todo_tag_ids, rec_todo_tag_ids) @@ -195,7 +195,7 @@ class DataController < ApplicationController # adjusts time to utc def adjust_time(timestring) - if (timestring == '') or (timestring == nil) + if (timestring == '') || (timestring == nil) return nil else return Time.parse(timestring + 'UTC') diff --git a/app/controllers/integrations_controller.rb b/app/controllers/integrations_controller.rb index dd2b841e..bb47497b 100644 --- a/app/controllers/integrations_controller.rb +++ b/app/controllers/integrations_controller.rb @@ -17,8 +17,8 @@ class IntegrationsController < ApplicationController end def search_plugin - @icon_data = [File.open(File.join(Rails.root, 'app', 'assets', 'images', 'done.png')).read]. - pack('m').gsub(/\n/, '') + @icon_data = [File.open(File.join(Rails.root, 'app', 'assets', 'images', 'done.png')).read] + .pack('m').gsub(/\n/, '') end def cloudmailin @@ -37,18 +37,18 @@ class IntegrationsController < ApplicationController private def process_message(message) - MessageGateway::receive(Mail.new(message)) + MessageGateway.receive(Mail.new(message)) end def verify_cloudmailin_signature provided = request.request_parameters.delete(:signature) - signature = Digest::MD5.hexdigest(flatten_params(request.request_parameters).sort.map{|k,v| v}.join + SITE_CONFIG['cloudmailin']) + signature = Digest::MD5.hexdigest(flatten_params(request.request_parameters).sort.map { |k, v| v }.join + SITE_CONFIG['cloudmailin']) return provided == signature end def flatten_params(params, title = nil, result = {}) params.each do |key, value| - if value.kind_of?(Hash) + if value.is_a? Hash key_name = title ? "#{title}[#{key}]" : key flatten_params(value, key_name, result) else diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb index ec6c7c30..af5a9232 100644 --- a/app/controllers/login_controller.rb +++ b/app/controllers/login_controller.rb @@ -15,8 +15,8 @@ class LoginController < ApplicationController cookies[:preferred_auth] = prefered_auth? unless cookies[:preferred_auth] case request.method when 'POST' - if @user = User.authenticate(params['user_login'], params['user_password']) - @user.update_attribute(:last_login_at, Time.now) + if (@user = User.authenticate(params['user_login'], params['user_password'])) + @user.update_attribute(:last_login_at, Time.zone.now) return handle_post_success else handle_post_failure @@ -43,8 +43,8 @@ class LoginController < ApplicationController if session return unless should_expire_sessions? # Get expiry time (allow ten seconds window for the case where we have none) - time_left = expiry_time - Time.now - @session_expired = ( time_left < (10 * 60) ) # Session will time out before the next check + time_left = expiry_time - Time.zone.now + @session_expired = (time_left < (10 * 60)) # Session will time out before the next check end end respond_to do |format| @@ -61,10 +61,10 @@ class LoginController < ApplicationController session['noexpiry'] = params['user_noexpiry'] msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire." notify :notice, "Login successful: session #{msg}" - cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => SITE_CONFIG['secure_cookies'] } + cookies[:tracks_login] = { :value => @user.login, :expires => Time.zone.now + 1.year, :secure => SITE_CONFIG['secure_cookies'] } unless should_expire_sessions? @user.remember_me - cookies[:auth_token] = { :value => @user.remember_token , :expires => @user.remember_token_expires_at, :secure => SITE_CONFIG['secure_cookies'] } + cookies[:auth_token] = { :value => @user.remember_token, :expires => @user.remember_token_expires_at, :secure => SITE_CONFIG['secure_cookies'] } end redirect_back_or_home end @@ -79,7 +79,7 @@ class LoginController < ApplicationController end def expiry_time - return Time.now + 10 unless session['expiry_time'] + return Time.zone.now + 10 unless session['expiry_time'] DateTime.strptime(session['expiry_time'], "%FT%T.%L%Z") end end diff --git a/app/controllers/mailgun_controller.rb b/app/controllers/mailgun_controller.rb index 0618a5a2..d3eac091 100644 --- a/app/controllers/mailgun_controller.rb +++ b/app/controllers/mailgun_controller.rb @@ -14,7 +14,7 @@ class MailgunController < ApplicationController todo = MessageGateway.receive(params['body-mime']) if todo - render :xml => todo.to_xml( *todo_xml_params ) + render :xml => todo.to_xml(*todo_xml_params) else render_failure "Todo not saved", 406 end diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb index ef44c114..5c14d3a0 100644 --- a/app/controllers/notes_controller.rb +++ b/app/controllers/notes_controller.rb @@ -8,7 +8,7 @@ class NotesController < ApplicationController @source_view = 'note_list' respond_to do |format| format.html - format.xml { render :xml => @all_notes.to_xml(:root => :notes, :except => :user_id) } + format.xml { render :xml => @all_notes.to_xml(:root => :notes, :except => :user_id) } end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 2c95b993..e116bb08 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -153,7 +153,7 @@ class ProjectsController < ApplicationController else @project_default_context = t('projects.default_context', :context => @project.default_context.name) end - cookies[:mobile_url]= { :value => request.fullpath, :secure => SITE_CONFIG['secure_cookies'] } + cookies[:mobile_url] = { :value => request.fullpath, :secure => SITE_CONFIG['secure_cookies'] } @mobile_from_project = @project.id end format.xml do @@ -245,7 +245,7 @@ class ProjectsController < ApplicationController respond_to do |format| format.js { render :template => template } - format.html { redirect_to :action => 'index'} + format.html { redirect_to :action => 'index' } format.xml do if @saved render :xml => @project.to_xml(:except => :user_id) diff --git a/app/controllers/recurring_todos/form_helper.rb b/app/controllers/recurring_todos/form_helper.rb index f7bbe962..574478b0 100644 --- a/app/controllers/recurring_todos/form_helper.rb +++ b/app/controllers/recurring_todos/form_helper.rb @@ -39,7 +39,7 @@ module RecurringTodos def method_missing(method, *args) # delegate daily_xxx to daily_pattern, weekly_xxx to weekly_pattern, etc. if method.to_s =~ /^([^_]+)_(.+)$/ - return @method_map[$1][:method].send(@method_map[$1][:prefix]+$2, *args) unless @method_map[$1].nil? + return @method_map[$1][:method].send(@method_map[$1][:prefix] + $2, *args) unless @method_map[$1].nil? end # no match, let @recurring_todo handle it, or fail diff --git a/app/controllers/recurring_todos_controller.rb b/app/controllers/recurring_todos_controller.rb index 9283459f..1d6ce146 100644 --- a/app/controllers/recurring_todos_controller.rb +++ b/app/controllers/recurring_todos_controller.rb @@ -18,11 +18,9 @@ class RecurringTodosController < ApplicationController @new_recurring_todo = RecurringTodo.new end - def new - end + def new; end - def show - end + def show; end def done @source_view = params['_source_view'] || 'recurring_todo' @@ -171,7 +169,7 @@ class RecurringTodosController < ApplicationController context_name: :context_name, project_name: :project_name, tag_list: :tag_list - }.each do |target,source| + }.each do |target, source| move_into_recurring_todo_param(params, target, source) end recurring_todo_params @@ -189,14 +187,14 @@ class RecurringTodosController < ApplicationController tag_list: :edit_recurring_todo_tag_list, end_date: :recurring_todo_edit_end_date, start_from: :recurring_todo_edit_start_from - }.each do |target,source| + }.each do |target, source| move_into_recurring_todo_param(params, target, source) end # make sure that we set weekly_return_xxx to empty (space) when they are # not checked (and thus not present in params["recurring_todo"]) %w{monday tuesday wednesday thursday friday saturday sunday}.each do |day| - params["recurring_todo"]["weekly_return_#{day}"]=' ' if params["recurring_todo"]["weekly_return_#{day}"].nil? + params["recurring_todo"]["weekly_return_#{day}"] = ' ' if params["recurring_todo"]["weekly_return_#{day}"].nil? end recurring_todo_params @@ -207,9 +205,15 @@ class RecurringTodosController < ApplicationController end def init - @days_of_week = (0..6).map{|i| [t('date.day_names')[i], i] } - @months_of_year = (1..12).map{|i| [t('date.month_names')[i], i] } - @xth_day = [[t('common.first'),1],[t('common.second'),2],[t('common.third'),3],[t('common.fourth'),4],[t('common.last'),5]] + @days_of_week = (0..6).map { |i| [t('date.day_names')[i], i] } + @months_of_year = (1..12).map { |i| [t('date.month_names')[i], i] } + @xth_day = [ + [t('common.first'), 1], + [t('common.second'), 2], + [t('common.third'), 3], + [t('common.fourth'), 4], + [t('common.last'),5] + ] @projects = current_user.projects.includes(:default_context) @contexts = current_user.contexts end @@ -221,10 +225,10 @@ class RecurringTodosController < ApplicationController def find_and_inactivate # find active recurring todos without active todos and inactivate them - current_user.recurring_todos.active. - select("recurring_todos.id, recurring_todos.state"). - joins("LEFT JOIN todos fai_todos ON (recurring_todos.id = fai_todos.recurring_todo_id) AND (NOT fai_todos.state='completed')"). - where("fai_todos.id IS NULL"). - each { |rt| current_user.recurring_todos.find(rt.id).toggle_completion! } + current_user.recurring_todos.active + .select("recurring_todos.id, recurring_todos.state") + .joins("LEFT JOIN todos fai_todos ON (recurring_todos.id = fai_todos.recurring_todo_id) AND (NOT fai_todos.state='completed')") + .where("fai_todos.id IS NULL") + .each { |rt| current_user.recurring_todos.find(rt.id).toggle_completion! } end end diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 1a8e6c39..0b6eb748 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -1,5 +1,5 @@ class StatsController < ApplicationController - SECONDS_PER_DAY = 86_400; + SECONDS_PER_DAY = 86_400 helper :todos, :projects, :recurring_todos append_before_action :init, :except => :index @@ -23,15 +23,15 @@ class StatsController < ApplicationController # less than the minimum completed_at, so no reason to check minimum completed_at # convert to array and fill in non-existing months - @actions_done_last_months_array = put_events_into_month_buckets(actions_last_months, month_count+1, :completed_at) - @actions_created_last_months_array = put_events_into_month_buckets(actions_last_months, month_count+1, :created_at) + @actions_done_last_months_array = put_events_into_month_buckets(actions_last_months, month_count + 1, :completed_at) + @actions_created_last_months_array = put_events_into_month_buckets(actions_last_months, month_count + 1, :created_at) # find max for graph in both hashes @max = (@actions_done_last_months_array + @actions_created_last_months_array).max # set running avg - @actions_done_avg_last_months_array = compute_running_avg_array(@actions_done_last_months_array,month_count + 1) - @actions_created_avg_last_months_array = compute_running_avg_array(@actions_created_last_months_array,month_count + 1) + @actions_done_avg_last_months_array = compute_running_avg_array(@actions_done_last_months_array, month_count + 1) + @actions_created_avg_last_months_array = compute_running_avg_array(@actions_created_last_months_array, month_count + 1) # interpolate avg for this month. @interpolated_actions_created_this_month = interpolate_avg_for_current_month(@actions_created_last_months_array) @@ -57,7 +57,7 @@ class StatsController < ApplicationController # last bar of the chart is selected. avtr is used for all other bars week_from = params['index'].to_i - week_to = week_from+1 + week_to = week_from + 1 @chart = Stats::Chart.new('actions_visible_running_time_data') @page_title = t('stats.actions_selected_from_week') @@ -117,7 +117,7 @@ class StatsController < ApplicationController @last_completed_projects = current_user.projects.completed.limit(10).reorder('completed_at DESC').includes(:todos, :notes) @last_completed_contexts = [] @last_completed_recurring_todos = current_user.recurring_todos.completed.limit(10).reorder('completed_at DESC').includes(:tags, :taggings) - #TODO: @last_completed_contexts = current_user.contexts.completed.all(:limit => 10, :order => 'completed_at DESC') + # TODO: @last_completed_contexts = current_user.contexts.completed.all(:limit => 10, :order => 'completed_at DESC') end private @@ -135,7 +135,7 @@ class StatsController < ApplicationController @cut_off_30days = 30.days.ago.beginning_of_day end - def get_ids_from (actions, week_from, week_to, at_end) + def get_ids_from(actions, week_from, week_to, at_end) selected_todo_ids = [] actions.each do |r| diff --git a/app/controllers/todos/todo_create_params_helper.rb b/app/controllers/todos/todo_create_params_helper.rb index 98c22cdb..717bc6a5 100644 --- a/app/controllers/todos/todo_create_params_helper.rb +++ b/app/controllers/todos/todo_create_params_helper.rb @@ -25,7 +25,8 @@ module Todos elsif params[:todo] @attributes = todo_params(params) end - @attributes = {} if @attributes.nil? # make sure there is at least an empty hash + # Make sure there is at least an empty hash + @attributes = {} if @attributes.nil? end def filter_tags @@ -41,7 +42,7 @@ module Todos def filter_starred if @params[:new_todo_starred] - @attributes["starred"] = (@params[:new_todo_starred]||"").include? "true" + @attributes["starred"] = (@params[:new_todo_starred] || "").include? "true" end end @@ -77,7 +78,7 @@ module Todos @params['predecessor_list'] end - def parse_dates() + def parse_dates @attributes['show_from'] = @user.prefs.parse_date(show_from) @attributes['due'] = @user.prefs.parse_date(due) @attributes['due'] ||= '' diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb index fae07c27..9c98c88d 100644 --- a/app/controllers/todos_controller.rb +++ b/app/controllers/todos_controller.rb @@ -38,7 +38,7 @@ class TodosController < ApplicationController @page_title = t('todos.task_list_title') # Set count badge to number of not-done, not hidden context items @count = current_user.todos.active.not_hidden.count(:all) - @todos_without_project = @not_done_todos.select{ |t| t.project.nil? } + @todos_without_project = @not_done_todos.select { |t| t.project.nil? } end format.m do @page_title = t('todos.mobile_todos_page_title') @@ -49,14 +49,14 @@ class TodosController < ApplicationController render :action => 'index'.freeze end - format.text do + format.text do # somehow passing Mime[:text] using content_type to render does not work headers['Content-Type'.freeze] = Mime[:text].to_s render :content_type => Mime[:text] end format.xml do @xml_todos = params[:limit_to_active_todos] ? @not_done_todos : @todos - render :xml => @xml_todos.to_xml( *[todo_xml_params[0].merge({ :root => :todos })] ) + render :xml => @xml_todos.to_xml(*[todo_xml_params[0].merge({ :root => :todos })]) end format.any(:rss, :atom) do @feed_title = 'Tracks Actions'.freeze @@ -70,7 +70,7 @@ class TodosController < ApplicationController @projects = current_user.projects.active @contexts = current_user.contexts respond_to do |format| - format.m { + format.m do @new_mobile = true @return_path = cookies[:mobile_url] ? cookies[:mobile_url] : mobile_path @mobile_from_context = current_user.contexts.find(params[:from_context]) if params[:from_context] @@ -79,7 +79,7 @@ class TodosController < ApplicationController # we have a project but not a context -> use the default context @mobile_from_context = @mobile_from_project.default_context end - } + end end end @@ -174,7 +174,8 @@ class TodosController < ApplicationController # first build all todos and check if they would validate on save params[:todo][:multiple_todos].split("\n").map do |line| - if line.present? #ignore blank lines + # Ignore blank lines + if line.present? @todo = current_user.todos.build({ :description => line, :context_id => p.context_id, :project_id => p.project_id }) validates &&= @todo.valid? @@ -245,12 +246,12 @@ class TodosController < ApplicationController @tag_name = params['_tag_name'] respond_to do |format| format.js - format.m { + format.m do @projects = current_user.projects.active @contexts = current_user.contexts @edit_mobile = true @return_path = cookies[:mobile_url] ? cookies[:mobile_url] : mobile_path - } + end end end @@ -258,7 +259,7 @@ class TodosController < ApplicationController @todo = current_user.todos.find(params['id']) respond_to do |format| format.m { render :action => 'show' } - format.xml { render :xml => @todo.to_xml( *[todo_xml_params[0].merge({ :root => :todo })] ) } + format.xml { render :xml => @todo.to_xml(*[todo_xml_params[0].merge({ :root => :todo })]) } end end @@ -339,7 +340,7 @@ class TodosController < ApplicationController determine_down_count determine_completed_count determine_deferred_tag_count(params['_tag_name']) if source_view_is(:tag) - @wants_redirect_after_complete = @todo.completed? && !@todo.project_id.nil? && current_user.prefs.show_project_on_todo_done && !source_view_is(:project) + @wants_redirect_after_complete = @todo.completed? && !@todo.project_id.nil? && current_user.prefs.show_project_on_todo_done && !source_view_is(:project) if source_view_is :calendar @original_item_due_id = get_due_id_for_calendar(@original_item.due) @old_due_empty = is_old_due_empty(@original_item_due_id) @@ -347,7 +348,7 @@ class TodosController < ApplicationController end render end - format.xml { render :xml => @todo.to_xml( *todo_xml_params ) } + format.xml { render :xml => @todo.to_xml(*todo_xml_params) } format.html do if @saved # TODO: I think this will work, but can't figure out how to test it @@ -355,10 +356,10 @@ class TodosController < ApplicationController redirect_to :action => "index" else notify(:notice, t("todos.action_marked_complete_error", :description => @todo.description, :completed => @todo.completed? ? 'complete' : 'incomplete'), "index") - redirect_to :action => "index" + redirect_to :action => "index" end end - format.m { + format.m do if @saved if cookies[:mobile_url] old_path = cookies[:mobile_url] @@ -372,7 +373,7 @@ class TodosController < ApplicationController else render :action => "edit", :format => :m end - } + end end end @@ -382,9 +383,9 @@ class TodosController < ApplicationController @saved = true # cannot determine error respond_to do |format| format.js - format.xml { render :xml => @todo.to_xml( *todo_xml_params ) } + format.xml { render :xml => @todo.to_xml(*todo_xml_params) } format.html { redirect_to request.referrer } - format.m { + format.m do if cookies[:mobile_url] old_path = cookies[:mobile_url] cookies[:mobile_url] = { :value => nil, :secure => SITE_CONFIG['secure_cookies'] } @@ -394,7 +395,7 @@ class TodosController < ApplicationController notify(:notice, "Star toggled") onsite_redirect_to todos_path(:format => 'm') end - } + end end end @@ -413,7 +414,7 @@ class TodosController < ApplicationController respond_to do |format| format.js { render :action => :update } - format.xml { render :xml => @todo.to_xml( *todo_xml_params ) } + format.xml { render :xml => @todo.to_xml(*todo_xml_params) } end end @@ -437,7 +438,7 @@ class TodosController < ApplicationController rescue ActiveRecord::RecordInvalid => exception record = exception.record if record.is_a?(Dependency) - record.errors.each { |key,value| @todo.errors[key] << value } + record.errors.each { |key, value| @todo.errors[key] << value } end @saved = false end @@ -462,12 +463,12 @@ class TodosController < ApplicationController @todo.touch_predecessors if @original_item.description != @todo.description respond_to do |format| - format.js { + format.js do @status_message = @todo.deferred? ? t('todos.action_saved_to_tickler') : t('todos.action_saved') @status_message = t('todos.added_new_project') + ' / ' + @status_message if @new_project_created @status_message = t('todos.added_new_context') + ' / ' + @status_message if @new_context_created - } - format.xml { render :xml => @todo.to_xml( *todo_xml_params ) } + end + format.xml { render :xml => @todo.to_xml(*todo_xml_params) } format.m do if @saved do_mobile_todo_redirection @@ -490,7 +491,8 @@ class TodosController < ApplicationController def destroy @source_view = params['_source_view'] || 'todo' @todo = current_user.todos.find(params['id']) - @original_item = current_user.todos.build(@todo.attributes) # create a (unsaved) copy of the original todo + # Create a (unsaved) copy of the original todo + @original_item = current_user.todos.build(@todo.attributes) @context_id = @todo.context_id @project_id = @todo.project_id @todo_was_destroyed = true @@ -558,7 +560,7 @@ class TodosController < ApplicationController format.html format.xml do completed_todos = current_user.todos.completed - render :xml => completed_todos.to_xml( *[todo_xml_params[0].merge({ :root => :todos })] ) + render :xml => completed_todos.to_xml(*[todo_xml_params[0].merge({ :root => :todos })]) end end end @@ -581,7 +583,7 @@ class TodosController < ApplicationController includes = params[:format] == 'xml' ? [:context, :project] : Todo::DEFAULT_INCLUDES @not_done_todos = current_user.todos.deferred.includes(includes).reorder('show_from') + current_user.todos.pending.includes(includes) - @todos_without_project = @not_done_todos.select{|t|t.project.nil?} + @todos_without_project = @not_done_todos.select { |t| t.project.nil? } @down_count = @count = @not_done_todos.size respond_to do |format| @@ -591,7 +593,7 @@ class TodosController < ApplicationController init_data_for_sidebar unless mobile? end format.m - format.xml { render :xml => @not_done_todos.to_xml( *[todo_xml_params[0].merge({ :root => :todos })] ) } + format.xml { render :xml => @not_done_todos.to_xml(*[todo_xml_params[0].merge({ :root => :todos })]) } end end @@ -625,23 +627,23 @@ class TodosController < ApplicationController todos_with_tag_ids = find_todos_with_tag_expr(@tag_expr) - @not_done_todos = todos_with_tag_ids. - active.not_hidden. - reorder(Arel.sql('todos.due IS NULL, todos.due ASC, todos.created_at ASC')). - includes(Todo::DEFAULT_INCLUDES) - @hidden_todos = todos_with_tag_ids. - hidden. - reorder(Arel.sql('todos.completed_at DESC, todos.created_at DESC')). - includes(Todo::DEFAULT_INCLUDES) - @deferred_todos = todos_with_tag_ids. - deferred. - reorder(Arel.sql('todos.show_from ASC, todos.created_at DESC')). - includes(Todo::DEFAULT_INCLUDES) - @pending_todos = todos_with_tag_ids. - blocked. - reorder(Arel.sql('todos.show_from ASC, todos.created_at DESC')). - includes(Todo::DEFAULT_INCLUDES) - @todos_without_project = @not_done_todos.select{ |t| t.project.nil? } + @not_done_todos = todos_with_tag_ids + .active.not_hidden + .reorder(Arel.sql('todos.due IS NULL, todos.due ASC, todos.created_at ASC')) + .includes(Todo::DEFAULT_INCLUDES) + @hidden_todos = todos_with_tag_ids + .hidden + .reorder(Arel.sql('todos.completed_at DESC, todos.created_at DESC')) + .includes(Todo::DEFAULT_INCLUDES) + @deferred_todos = todos_with_tag_ids + .deferred + .reorder(Arel.sql('todos.show_from ASC, todos.created_at DESC')) + .includes(Todo::DEFAULT_INCLUDES) + @pending_todos = todos_with_tag_ids + .blocked + .reorder(Arel.sql('todos.show_from ASC, todos.created_at DESC')) + .includes(Todo::DEFAULT_INCLUDES) + @todos_without_project = @not_done_todos.select { |t| t.project.nil? } # If you've set no_completed to zero, the completed items box isn't shown on # the tag page @@ -664,12 +666,8 @@ class TodosController < ApplicationController respond_to do |format| format.html - format.m { - cookies[:mobile_url]= { :value => request.fullpath, :secure => SITE_CONFIG['secure_cookies'] } - } - format.text { - render :action => 'index', :layout => false, :content_type => Mime[:text] - } + format.m { cookies[:mobile_url] = { :value => request.fullpath, :secure => SITE_CONFIG['secure_cookies'] } } + format.text { render :action => 'index', :layout => false, :content_type => Mime[:text] } end end @@ -706,7 +704,7 @@ class TodosController < ApplicationController tags_all -= tags_beginning respond_to do |format| - format.autocomplete { render :body => for_autocomplete(tags_beginning+tags_all, params[:term]) } + format.autocomplete { render :body => for_autocomplete(tags_beginning + tags_all, params[:term]) } end end @@ -715,7 +713,8 @@ class TodosController < ApplicationController numdays = params['days'].to_i @todo = current_user.todos.find(params[:id]) - @original_item = current_user.todos.build(@todo.attributes) # create a (unsaved) copy of the original todo + # Create a (unsaved) copy of the original todo + @original_item = current_user.todos.build(@todo.attributes) @todo_deferred_state_changed = true @new_context_created = false @@ -750,7 +749,7 @@ class TodosController < ApplicationController def list_hidden @hidden = current_user.todos.hidden respond_to do |format| - format.xml { render :xml => @hidden.to_xml( *[todo_xml_params[0].merge({ :root => :todos })] ) } + format.xml { render :xml => @hidden.to_xml(*[todo_xml_params[0].merge({ :root => :todos })]) } end end @@ -843,7 +842,7 @@ class TodosController < ApplicationController end def tag_title(tag_expr) - and_list = tag_expr.inject([]) { |s,tag_list| s << tag_list.join(',') } + and_list = tag_expr.inject([]) { |s, tag_list| s << tag_list.join(',') } return and_list.join(' AND ') end @@ -905,7 +904,7 @@ end end def find_todos_with_tag_expr(tag_expr) - # optimize for the common case: selecting only one tag + # Optimize for the common case of selecting only one tag if @single_tag tag = current_user.tags.where(:name => @tag_name).first tag_id = tag.nil? ? -1 : tag.id @@ -1184,7 +1183,8 @@ end def update_tags if params[:tag_list] @todo.tag_with(params[:tag_list]) - @todo.tags.reload #force a reload for proper rendering + # Force a reload for proper rendering + @todo.tags.reload end end @@ -1197,7 +1197,7 @@ end end def update_date_for_update(key) - params['todo'][key] = params["todo"].has_key?(key) ? parse_date_for_update(params["todo"][key], t("todos.error.invalid_#{key}_date")) : "" + params['todo'][key] = params["todo"].key?(key) ? parse_date_for_update(params["todo"][key], t("todos.error.invalid_#{key}_date")) : "" end def update_due_and_show_from_dates @@ -1225,7 +1225,7 @@ end # assumes @todo.save was called so that the predecessor_list is persistent original_item_predecessor_list = @original_item.predecessors - .map{ |t| t.specification } + .map { |t| t.specification } .join(', ') if original_item_predecessor_list != params[:predecessor_list] diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 54aa94f2..8198025a 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -92,12 +92,12 @@ class UsersController < ApplicationController return end - signup_by_admin = true if (@user && @user.is_admin?) + signup_by_admin = true if @user && @user.is_admin? first_user_signing_up = User.no_users_yet? user.is_admin = true if first_user_signing_up if user.save @user = User.authenticate(user.login, params['user']['password']) - @user.create_preference({ :locale => I18n.locale }) + @user.create_preference(:locale => I18n.locale) @user.save session['user_id'] = @user.id unless signup_by_admin notify :notice, t('users.signup_successful', :username => @user.login) @@ -219,10 +219,10 @@ class UsersController < ApplicationController end def check_create_user_params - return false unless params.has_key?(:user) - return false unless params[:user].has_key?(:login) + return false unless params.key?(:user) + return false unless params[:user].key?(:login) return false if params[:user][:login].empty? - return false unless params[:user].has_key?(:password) + return false unless params[:user].key?(:password) return false if params[:user][:password].empty? return true end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e0887bb1..5380a238 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -10,7 +10,7 @@ module ApplicationHelper link_to( t("layouts.navigation.group_view_by_#{menu_name}"), '#', - { :id => "group_view_by_link", :accesskey => "g", :title => t('layouts.navigation.group_view_by_title'), :x_current_group_by => @group_view_by } ) + { :id => "group_view_by_link", :accesskey => "g", :title => t('layouts.navigation.group_view_by_title'), :x_current_group_by => @group_view_by }) end end @@ -44,7 +44,7 @@ module ApplicationHelper end def count_undone_todos_phrase_text(todos_parent) - count_undone_todos_phrase(todos_parent).gsub(" "," ").html_safe + count_undone_todos_phrase(todos_parent).gsub(" ", " ").html_safe end def count_undone_todos_and_notes_phrase(project) @@ -116,7 +116,7 @@ module ApplicationHelper recurring_target + recurrence_pattern + recurrence_time_span end - def date_format_for_date_picker() + def date_format_for_date_picker [ ['%m', 'mm'], ['%b', 'M'], @@ -129,8 +129,8 @@ module ApplicationHelper ].inject(current_user.prefs.date_format) { |str, translation| str.gsub(*translation) } end - def sidebar_html_for_titled_list (list, title) - return content_tag(:h3, title+" (#{list.size})") + content_tag(:ul, sidebar_html_for_list(list)) + def sidebar_html_for_titled_list(list, title) + return content_tag(:h3, title + " (#{list.size})") + content_tag(:ul, sidebar_html_for_list(list)) end def link_to_sidebar_item(item) @@ -162,7 +162,7 @@ module ApplicationHelper common.update common.create common.ajaxError todos.unresolved_dependency }.each do |s| - js << "i18n['#{s}'] = '#{ t(s).gsub(/'/, "\\\\'") }';\n" + js << "i18n['#{s}'] = '#{t(s).gsub(/'/, "\\\\'")}';\n" end return js.html_safe end @@ -222,7 +222,7 @@ module ApplicationHelper end def link_to_edit(type, object, descriptor) - link_to(descriptor, self.send("edit_#{type}_path", object), + link_to(descriptor, send("edit_#{type}_path", object), { :id => "link_edit_#{dom_id(object)}", :class => "#{type}_edit_settings icon" diff --git a/app/helpers/bootstrap_flash_helper.rb b/app/helpers/bootstrap_flash_helper.rb index 04ea47bf..85d3ca3d 100644 --- a/app/helpers/bootstrap_flash_helper.rb +++ b/app/helpers/bootstrap_flash_helper.rb @@ -5,9 +5,9 @@ module BootstrapFlashHelper :error => :danger, :info => :info, :warning => :warning - } unless const_defined?(:ALERT_MAPPING) + }.freeze unless const_defined?(:ALERT_MAPPING) - def bootstrap_flash(options = {:close_button => true}) + def bootstrap_flash(options = { :close_button => true }) flash_messages = [] flash.each do |type, message| # Skip empty messages, e.g. for devise messages set to nothing in a locale file. @@ -15,7 +15,6 @@ module BootstrapFlashHelper type = type.to_sym next unless ALERT_MAPPING.keys.include?(type) - tag_class = options.extract!(:class)[:class] tag_options = { class: "alert fade in alert-#{ALERT_MAPPING[type]} #{tag_class}" diff --git a/app/helpers/contexts_helper.rb b/app/helpers/contexts_helper.rb index 472b968b..edb53116 100644 --- a/app/helpers/contexts_helper.rb +++ b/app/helpers/contexts_helper.rb @@ -1,9 +1,9 @@ module ContextsHelper def show_context_name(context) if source_view_is :context - content_tag(:span, :id => "context_name"){context.name} + content_tag(:span, :id => "context_name"){ context.name } else - link_to_context( context ) + link_to_context(context) end end @@ -11,7 +11,7 @@ module ContextsHelper link_to_delete(:context, context, descriptor) end - def link_to_edit_context (context, descriptor = sanitize(context.name)) + def link_to_edit_context(context, descriptor = sanitize(context.name)) link_to_edit(:context, context, descriptor) end diff --git a/app/helpers/date_label_helper.rb b/app/helpers/date_label_helper.rb index 68b5435c..464c794e 100644 --- a/app/helpers/date_label_helper.rb +++ b/app/helpers/date_label_helper.rb @@ -10,7 +10,7 @@ module DateLabelHelper :tomorrow => :amber, :this_week => :orange, :more_than_a_week => :green - } + }.freeze def initialize(date, prefs) @date = date @@ -51,19 +51,15 @@ module DateLabelHelper def date_html_wrapper return "" if @date.nil? - return content_tag(:a, {:title => @prefs.format_date(@date)}) { - content_tag(:span, {:class => get_color}) { - yield - } + return content_tag(:a, { :title => @prefs.format_date(@date) }) { + content_tag(:span, { :class => get_color }) { yield } } end def date_mobile_html_wrapper return "" if @date.nil? - return content_tag(:span, {:class => get_color}) { - yield - } + return content_tag(:span, { :class => get_color }) { yield } end end diff --git a/app/helpers/feedlist_helper.rb b/app/helpers/feedlist_helper.rb index 4a912a83..70f0a904 100644 --- a/app/helpers/feedlist_helper.rb +++ b/app/helpers/feedlist_helper.rb @@ -1,6 +1,6 @@ module FeedlistHelper def linkoptions(format, options) - merge_hashes( { :format => format }, options, user_token_hash) + merge_hashes({ :format => format }, options, user_token_hash) end def rss_formatted_link(options = {}) @@ -41,7 +41,7 @@ module FeedlistHelper protected def merge_hashes(*hashes) - hashes.inject(Hash.new){ |result, h| result.merge(h) } + hashes.inject({}) { |result, h| result.merge(h) } end def user_token_hash diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb index 0e62f5a4..9d046098 100644 --- a/app/helpers/notes_helper.rb +++ b/app/helpers/notes_helper.rb @@ -11,9 +11,8 @@ module NotesHelper link_to( descriptor, note_path(note, :format => 'js'), - {:id => "delete_note_#{note.id}", :class => "delete_note_button", - :title => t('notes.delete_note_title', :id => note.id), :x_confirm_message => t('notes.delete_note_confirm', :id => note.id)} + { :id => "delete_note_#{note.id}", :class => "delete_note_button", + :title => t('notes.delete_note_title', :id => note.id), :x_confirm_message => t('notes.delete_note_confirm', :id => note.id) } ) end - end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 2ce15824..bd2e6ada 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -1,9 +1,9 @@ module ProjectsHelper def show_project_name(project) if source_view_is :project - content_tag(:span, :id => "project_name"){project.name} + content_tag(:span, :id => "project_name") { project.name } else - link_to_project( project ) + link_to_project(project) end end @@ -14,7 +14,7 @@ module ProjectsHelper end def project_next_prev - content_tag(:div, :id=>"project-next-prev") do + content_tag(:div, :id => "project-next-prev") do html = "" html << link_to_project(@previous_project, "« #{@previous_project.shortened_name}".html_safe) if @previous_project html << " | " if @previous_project && @next_project @@ -33,14 +33,13 @@ module ProjectsHelper def project_summary(project) project_description = '' - project_description += render_text( project.description ) if project.description.present? + project_description += render_text(project.description) if project.description.present? project_description += content_tag(:p, - "#{count_undone_todos_phrase(p)}. #{t('projects.project_state', :state => project.state)}".html_safe - ) + "#{count_undone_todos_phrase(p)}. #{t('projects.project_state', :state => project.state)}".html_safe) end def needsreview_class(item) - raise "item must be a Project " unless item.kind_of? Project + raise "item must be a Project " unless item.is_a? Project return item.needs_review?(current_user) ? "needsreview" : "needsnoreview" end @@ -48,7 +47,7 @@ module ProjectsHelper link_to_delete(:project, project, descriptor) end - def link_to_edit_project (project, descriptor = sanitize(project.name)) + def link_to_edit_project(project, descriptor = sanitize(project.name)) link_to_edit(:project, project, descriptor) end end diff --git a/app/helpers/recurring_todos_helper.rb b/app/helpers/recurring_todos_helper.rb index 7f6fe459..895f02cb 100644 --- a/app/helpers/recurring_todos_helper.rb +++ b/app/helpers/recurring_todos_helper.rb @@ -1,8 +1,8 @@ module RecurringTodosHelper def recurring_todo_tag_list - tags_except_starred = @recurring_todo.tags.reject{ |t| t.name == Todo::STARRED_TAG_NAME } + tags_except_starred = @recurring_todo.tags.reject { |t| t.name == Todo::STARRED_TAG_NAME } tag_list = tags_except_starred - .collect{ |t| content_tag(:span,link_to(t.name, tag_path(t.name)), :class => "tag #{t.label}") } + .collect { |t| content_tag(:span, link_to(t.name, tag_path(t.name)), :class => "tag #{t.label}") } .join('') return content_tag :span, tag_list.html_safe, :class => "tags" end diff --git a/app/helpers/rendering_helper.rb b/app/helpers/rendering_helper.rb index 56f304d0..ad406aa6 100644 --- a/app/helpers/rendering_helper.rb +++ b/app/helpers/rendering_helper.rb @@ -21,7 +21,7 @@ module RenderingHelper def render_text(text) rendered = auto_link_message(text) rendered = textile(rendered) - rendered = auto_link(rendered, link: :urls, html: {target: '_blank'}) + rendered = auto_link(rendered, link: :urls, html: { target: '_blank' }) relaxed_config = Sanitize::Config::RELAXED config = relaxed_config diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 6e9f7d8f..3f74747e 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -3,17 +3,17 @@ require 'staleness' module TodosHelper # === helpers for rendering container def empty_message_holder(container_name, show, title_param = nil) - content_tag(:div, :id => "no_todos_in_view", :class => "container #{container_name}", :style => "display:" + (show ? "block" : "none") ) do - content_tag(:h2) { t("todos.no_actions.title", :param=>title_param) } + + content_tag(:div, :id => "no_todos_in_view", :class => "container #{container_name}", :style => "display:" + (show ? "block" : "none")) do + content_tag(:h2) { t("todos.no_actions.title", :param => title_param) } + content_tag(:div, :class => "message") do - content_tag(:p) { t("todos.no_actions.#{container_name}", :param=>title_param) } + content_tag(:p) { t("todos.no_actions.#{container_name}", :param => title_param) } end end end def todos_container_empty_message(container_name, container_id, show_message) content_tag(:div, :id => "#{container_id}-empty-d", :style => "display:#{show_message ? 'block' : 'none'}") do - content_tag(:div, :class=>"message") do + content_tag(:div, :class => "message") do content_tag(:p) do t("todos.no_actions.#{container_name}") end @@ -27,7 +27,7 @@ module TodosHelper :collapsible => true, :show_empty_containers => @show_empty_containers, :parent_container_type => @group_view_by - })}) + }) }) end def default_collection_settings @@ -73,10 +73,10 @@ module TodosHelper def show_deferred_pending_todos(deferred_todos, pending_todos, settings = {}) settings[:pending] = pending_todos - settings[:container_name]="deferred_pending" + settings[:container_name] = "deferred_pending" render :partial => "todos/collection", - :object => deferred_todos+pending_todos, + :object => deferred_todos + pending_todos, :locals => { :settings => settings.reverse_merge!(default_collection_settings) } end @@ -113,7 +113,7 @@ module TodosHelper settings.reverse_merge!({ :title => t("todos.actions.#{settings[:parent_container_type]}_#{settings[:container_name]}", :param => settings[:title_param]) }) - header = settings[:link_in_header].nil? ? "" : content_tag(:div, :class=>"link_in_container_header"){settings[:link_in_header]} + header = settings[:link_in_header].nil? ? "" : content_tag(:div, :class => "link_in_container_header") { settings[:link_in_header] } header += content_tag(:h2) do toggle = settings[:collapsible] ? container_toggle("toggle_#{settings[:id]}") : "" "#{toggle} #{settings[:title]} #{settings[:append_descriptor]}".html_safe @@ -123,7 +123,7 @@ module TodosHelper end def todos_container_items(collection, settings = {}) - settings.reverse_merge!({:id => "#{settings[:container_name]}"}) + settings.reverse_merge!({ :id => "#{settings[:container_name]}" }) # do not pass :class to partial locals settings.delete(:class) @@ -140,7 +140,7 @@ module TodosHelper :collapsible => false, :show_empty_containers => true, :container_name => "#{period}", - :title =>t("todos.calendar.#{period}", :month => l(Time.zone.now, :format => "%B"), :next_month => l(1.month.from_now, :format => "%B")) + :title => t("todos.calendar.#{period}", :month => l(Time.zone.now, :format => "%B"), :next_month => l(1.month.from_now, :format => "%B")) } } end @@ -168,12 +168,13 @@ module TodosHelper :class => "icon_delete_item", :id => dom_id(todo, "delete"), :x_confirm_message => t('todos.confirm_delete', :description => todo.description), - :title => t('todos.delete_action')); + :title => t('todos.delete_action') + ) end def remote_defer_menu_item(days, todo) url = { :controller => 'todos', :action => 'defer', :id => todo.id, :days => days, - :_source_view => (@source_view.underscore.gsub(/\s+/,'_') rescue "") } + :_source_view => (@source_view.underscore.gsub(/\s+/, '_') rescue "") } url[:_tag_name] = @tag_name if @source_view == 'tag' options = { :x_defer_alert => false, :class => "icon_defer_item icon_defer_#{days}_item", :id => "defer_#{days}_#{dom_id(todo)}" } @@ -192,13 +193,13 @@ module TodosHelper link_to( image_tag("blank.png", :title => t('todos.remove_dependency'), :align => "absmiddle", :class => "delete_item"), remove_predecessor_todo_path(todo), - {:class => "delete_dependency_button", :x_predecessors_id => predecessor.id} + { :class => "delete_dependency_button", :x_predecessors_id => predecessor.id } ) end def remote_promote_to_project_menu_item(todo) - url = {:controller => 'todos', :action => 'convert_to_project', :id => todo.id, - :_source_view => (@source_view.underscore.gsub(/\s+/,'_') rescue "")} + url = { :controller => 'todos', :action => 'convert_to_project', :id => todo.id, + :_source_view => (@source_view.underscore.gsub(/\s+/, '_') rescue "") } url[:_tag_name] = @tag_name if @source_view == 'tag' link_to(t('todos.convert_to_project'), url, { :class => "icon_item_to_project", :id => dom_id(todo, "to_project") }) @@ -206,7 +207,7 @@ module TodosHelper def attachment_image(todo) link_to( - image_tag('blank.png', width: 16, height: 16, border:0), + image_tag('blank.png', width: 16, height: 16, border: 0), todo.attachments.first.file.url, { :class => 'todo_attachment', title: 'Get attachments of this todo' } ) @@ -214,23 +215,23 @@ module TodosHelper def collapsed_notes_image(todo) link = link_to( - image_tag( 'blank.png', :width => '16', :height => '16', :border => '0' ), + image_tag('blank.png', :width => '16', :height => '16', :border => '0'), "#", { :class => 'show_notes', :title => 'Show notes' }) notes = content_tag(:div, { :class => "todo_notes", :id => dom_id(todo, 'notes'), :style => "display:none" }) { raw render_text(todo.notes) } - return link+notes + return link + notes end def collapsed_successors_image(todo) - link = link_to(image_tag('blank.png', :width => '16', :height => '16', :border => '0' ), "#", { :class => 'show_successors', :title => 'Show successors' }) + link = link_to(image_tag('blank.png', :width => '16', :height => '16', :border => '0'), "#", { :class => 'show_successors', :title => 'Show successors' }) successors = content_tag(:div, { :class => "todo_successors", :id => dom_id(todo, 'successors'), :style => "display:none" }) do render :partial => "todos/successor", :collection => todo.pending_successors, :locals => { :parent_container_type => parent_container_type, :suppress_dependencies => true, :predecessor => todo } end - return link+successors + return link + successors end def image_tag_for_recurring_todo(todo) @@ -257,9 +258,9 @@ module TodosHelper def date_span(todo = @todo) if todo.completed? - content_tag(:span, { :class => :grey }) { format_date( todo.completed_at ) } + content_tag(:span, { :class => :grey }) { format_date(todo.completed_at) } elsif todo.pending? - title = t('todos.depends_on')+ ": " + todo.uncompleted_predecessors.to_a.map(&:description).join(', ') + title = t('todos.depends_on') + ": " + todo.uncompleted_predecessors.to_a.map(&:description).join(', ') content_tag(:a, { :title => title }) { content_tag(:span, { :class => :orange }) { t('todos.pending') } } elsif todo.deferred? show_date(todo.show_from) @@ -318,7 +319,7 @@ module TodosHelper end def include_context_link(todo, parent_container_type) - return true if (['stats', 'search'].include?(parent_container_type)) + return true if ['stats', 'search'].include?(parent_container_type) # TODO: remove next line if 'project' supports group_view_by return true if parent_container_type == 'project' return true if @group_view_by == 'project' @@ -327,7 +328,7 @@ module TodosHelper def include_project_link(todo, parent_container_type) return false unless todo.has_project? - return true if (['stats', 'search'].include?(parent_container_type)) + return true if ['stats', 'search'].include?(parent_container_type) # TODO: remove next line if 'context' supports group_view_by return true if parent_container_type == 'context' return true if @group_view_by == 'context' @@ -347,9 +348,9 @@ module TodosHelper case days_stale when 0...start "" - when start...start*2 + when start...start * 2 " stale_l1" - when start*2...start*3 + when start*2...start * 3 " stale_l2" else " stale_l3" @@ -380,19 +381,19 @@ module TodosHelper def default_contexts_for_autocomplete projects = current_user.projects.uncompleted.includes(:default_context).where('NOT(default_context_id IS NULL)') - Hash[*projects.map{ |p| [escape_javascript(p.name), escape_javascript(p.default_context.name)] }.flatten].to_json + Hash[*projects.map { |p| [escape_javascript(p.name), escape_javascript(p.default_context.name)] }.flatten].to_json end def default_tags_for_autocomplete projects = current_user.projects.uncompleted.where("NOT(default_tags = '')") - Hash[*projects.map{ |p| [escape_javascript(p.name), p.default_tags] }.flatten].to_json + Hash[*projects.map { |p| [escape_javascript(p.name), p.default_tags] }.flatten].to_json end # === various helpers def formatted_pagination(total) s = will_paginate(@todos) - (s.gsub(/(<\/[^<]+>)/, '\1 ')).chomp(' ') + s.gsub(/(<\/[^<]+>)/, '\1 ').chomp(' ') end def format_ical_notes(notes) @@ -418,10 +419,11 @@ module TodosHelper # if the animation needs to be run inside the namespace of an object, set the # object_name to the name of the object and this name will be prepended to each step def render_animation(animation, object_name = nil) - object_name += "." unless object_name.nil? # add dot if object_name is given + # Add dot if object_name is given + object_name += "." unless object_name.nil? # concatenate all steps into functions that call functions - html = animation.map{ |step| "#{object_name}#{step}({ go: function() {" }.join("\r\n") + html = animation.map { |step| "#{object_name}#{step}({ go: function() {" }.join("\r\n") # close all functions html += "}}) " * animation.size + ";" @@ -474,8 +476,8 @@ module TodosHelper end def todo_container_is_empty - default_container_empty = ( @down_count == 0 ) - deferred_container_empty = ( @todo.deferred? && @remaining_deferred_count == 0) + default_container_empty = (@down_count == 0) + deferred_container_empty = (@todo.deferred? && @remaining_deferred_count == 0) return default_container_empty || deferred_container_empty end @@ -516,12 +518,12 @@ module TodosHelper def update_needs_to_remove_todo_from_container source_view do |page| page.context { return @context_changed || @todo_deferred_state_changed || @todo_pending_state_changed || @todo_should_be_hidden } - page.project { return @context_changed || @todo_deferred_state_changed || @todo_pending_state_changed || @project_changed} + page.project { return @context_changed || @todo_deferred_state_changed || @todo_pending_state_changed || @project_changed } page.deferred { return todo_moved_out_of_container || !(@todo.deferred? || @todo.pending?) } page.calendar { return @due_date_changed || !@todo.due } page.stats { return @todo.completed? } - page.tag { return ( (@context_changed | @project_changed) && !@todo.hidden?) || @tag_was_removed || @todo_hidden_state_changed || @todo_deferred_state_changed } - page.todo { return todo_moved_out_of_container || @todo.hidden? || @todo.deferred? || @todo.pending?} + page.tag { return ((@context_changed | @project_changed) && !@todo.hidden?) || @tag_was_removed || @todo_hidden_state_changed || @todo_deferred_state_changed } + page.todo { return todo_moved_out_of_container || @todo.hidden? || @todo.deferred? || @todo.pending? } page.search { return false } end return false @@ -564,7 +566,7 @@ module TodosHelper source_view do |page| page.context { return @remaining_in_context == 0 } end - return @down_count==0 + return @down_count == 0 end def project_container_id(todo) @@ -609,29 +611,25 @@ module TodosHelper raise Exception.new, "no @todo or @successor set" if !todo source_view do |page| - page.project { + page.project do return "deferred_pending_container-empty-d" if empty_criteria_met return todo_container_empty_id(todo) - } - page.tag { + end + page.tag do return "deferred_pending_container-empty-d" if empty_criteria_met return "hidden_container-empty-d" if @todo.hidden? return todo_container_empty_id(todo) - } - page.calendar { + end + page.calendar do return "deferred_pending_container-empty-d" if empty_criteria_met return "#{@new_due_id}_container-empty-d" - } - page.context { + end + page.context do return "deferred_pending_container-empty-d" if empty_criteria_met return todo_container_empty_id(todo) - } - page.todo { - return todo_container_empty_id(todo) - } - page.deferred { - return todo_container_empty_id(todo) - } + end + page.todo { return todo_container_empty_id(todo) } + page.deferred { return todo_container_empty_id(todo) } end return context_container_empty_id(todo) @@ -656,28 +654,28 @@ module TodosHelper def show_empty_message_in_source_container container_id = "" source_view do |page| - page.project { + page.deferred { container_id = todo_container_empty_id(@original_item) if @remaining_in_context == 0 } + page.calendar { container_id = "#{@original_item_due_id}_container-empty-d" if @old_due_empty } + page.todo { container_id = context_container_empty_id(@original_item) if @remaining_in_context == 0 } + page.done { container_id = "completed_#{@original_completed_period}_container-empty-d" if @remaining_in_context == 0 } + page.all_done { container_id = "all-done-empty-nd" if @remaining_in_context == 0 } + page.project do container_id = project_container_empty_id(@original_item) if @remaining_in_context == 0 container_id = "deferred_pending_container-empty-d" if todo_was_removed_from_deferred_or_blocked_container && @remaining_deferred_or_pending_count == 0 container_id = "completed_container-empty-d" if @completed_count && @completed_count == 0 && !@todo.completed? - } - page.deferred { container_id = todo_container_empty_id(@original_item) if @remaining_in_context == 0 } - page.calendar { container_id = "#{@original_item_due_id}_container-empty-d" if @old_due_empty } - page.tag { + end + page.tag do container_id = "hidden_container-empty-d" if (@remaining_hidden_count == 0 && !@todo.hidden? && @todo_hidden_state_changed) || (@remaining_hidden_count == 0 && @todo.completed? && @original_item.hidden?) container_id = "deferred_pending_container-empty-d" if (todo_was_removed_from_deferred_or_blocked_container && @remaining_deferred_or_pending_count == 0) || (@original_item.deferred? && @remaining_deferred_or_pending_count == 0 && (@todo.completed? || @tag_was_removed)) container_id = "completed_container-empty-d" if @completed_count && @completed_count == 0 && !@todo.completed? - } - page.context { + end + page.context do container_id = context_container_empty_id(@original_item) if @remaining_in_context == 0 container_id = "deferred_pending_container-empty-d" if todo_was_removed_from_deferred_or_blocked_container && @remaining_deferred_or_pending_count == 0 container_id = "completed_container-empty-d" if @completed_count && @completed_count == 0 && !@todo.completed? - } - page.todo { container_id = context_container_empty_id(@original_item) if @remaining_in_context == 0 } - page.done { container_id = "completed_#{@original_completed_period}_container-empty-d" if @remaining_in_context == 0 } - page.all_done { container_id = "all-done-empty-nd" if @remaining_in_context == 0 } + end end return container_id.blank? ? "" : "$(\"##{container_id}\").slideDown(100);".html_safe end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 8fdbf5ed..0154872c 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -2,11 +2,12 @@ module UsersHelper def remote_delete_user(user) return link_to( image_tag("blank.png", :title => t('users.destroy_user'), :class => "delete_item"), - url_for({:controller => 'users', :action => 'destroy', :id => user.id}), - { :id => "delete_user_#{user.id}", + url_for(:controller => 'users', :action => 'destroy', :id => user.id), { + :id => "delete_user_#{user.id}", :class => "delete_user_button", :title => t('users.destroy_user'), :x_confirm_message => t('users.destroy_confirmation', :login => user.login) - }) + } + ) end end diff --git a/app/models/context.rb b/app/models/context.rb index 407f15e9..d2594f66 100644 --- a/app/models/context.rb +++ b/app/models/context.rb @@ -31,9 +31,7 @@ class Context < ApplicationRecord end end - validates_presence_of :name, :message => "context must have a name" - validates_length_of :name, :maximum => 255, :message => "context name must be less than 256 characters" - validates_uniqueness_of :name, :message => "already exists", :scope => "user_id", :case_sensitive => false + validates :name, presence: { message: "context must have a name" }, length: { maximum: 255, message: "context name must be less than 256 characters" }, uniqueness: { message: "already exists", scope: "user_id", case_sensitive: false } def self.null_object NullContext.new diff --git a/app/models/message_gateway.rb b/app/models/message_gateway.rb index 38278297..711e6a92 100644 --- a/app/models/message_gateway.rb +++ b/app/models/message_gateway.rb @@ -75,7 +75,7 @@ class MessageGateway < ActionMailer::Base def get_receiving_user_from_mail_header(email) user = get_receiving_user_from_sms_email(get_address(email)) - Rails.logger.info(user.nil? ? "User unknown": "Email belongs to #{user.login}") + Rails.logger.info(user.nil? ? "User unknown" : "Email belongs to #{user.login}") return user end @@ -98,8 +98,8 @@ class MessageGateway < ActionMailer::Base return true end - def sender_is_in_mailmap?(user,email) - if SITE_CONFIG['mailmap'].is_a? Hash and SITE_CONFIG['email_dispatch'] == 'to' + def sender_is_in_mailmap?(user, email) + if (SITE_CONFIG['mailmap'].is_a? Hash) && SITE_CONFIG['email_dispatch'] == 'to' # Look for the sender in the map of allowed senders SITE_CONFIG['mailmap'][user.preference.sms_email].include? email.from[0] else diff --git a/app/models/project.rb b/app/models/project.rb index 0820f10f..6e965a52 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -16,9 +16,7 @@ class Project < ApplicationRecord before_create :set_last_reviewed_now - validates_presence_of :name - validates_length_of :name, :maximum => 255 - validates_uniqueness_of :name, :scope => "user_id", :case_sensitive => true + validates :name, presence: true, length: { maximum: 255 }, uniqueness: { scope: :user_id } acts_as_list :scope => 'user_id = #{user_id} AND state = \'#{state}\'', :top_of_list => 0 @@ -88,21 +86,21 @@ class Project < ApplicationRecord end def needs_review?(user) - return active? && ( last_reviewed.nil? || + return active? && (last_reviewed.nil? || (last_reviewed < Time.current - user.prefs.review_period.days)) end def blocked? ## mutually exclusive for stalled and blocked # blocked is uncompleted project with deferred or pending todos, but no next actions - return false if self.completed? - return !self.todos.deferred_or_blocked.empty? && self.todos.active.empty? + return false if completed? + return !todos.deferred_or_blocked.empty? && todos.active.empty? end def stalled? # Stalled projects are active projects with no active next actions - return false if self.completed? || self.hidden? - return !self.todos.deferred_or_blocked.exists? && !self.todos.active.exists? + return false if completed? || hidden? + return !todos.deferred_or_blocked.exists? && !todos.active.exists? end def shortened_name(length = 40) diff --git a/app/models/recurring_todo.rb b/app/models/recurring_todo.rb index 0816a48c..70d1a498 100644 --- a/app/models/recurring_todo.rb +++ b/app/models/recurring_todo.rb @@ -24,10 +24,12 @@ class RecurringTodo < ApplicationRecord end end - validates_presence_of :description, :recurring_period, :target, :ends_on, :context - - validates_length_of :description, :maximum => 100 - validates_length_of :notes, :maximum => 60_000, :allow_nil => true + validates :description, presence: true, length: { maximum: 100 } + validates :notes, length: { maximum: 60_000, allow_nil: true } + validates :recurring_period, presence: true + validates :target, presence: true + validates :ends_on, presence: true + validates :context, presence: true validate :period_validation validate :pattern_specific_validations @@ -118,12 +120,12 @@ class RecurringTodo < ApplicationRecord def remove_from_project! self.project = nil - self.save + save end def clear_todos_association unless todos.nil? - self.todos.each do |t| + todos.each do |t| t.recurring_todo = nil t.save end @@ -132,7 +134,7 @@ class RecurringTodo < ApplicationRecord def increment_occurrences self.occurrences_count += 1 - self.save + save end def continues_recurring?(previous) diff --git a/app/models/recurring_todos/abstract_recurrence_pattern.rb b/app/models/recurring_todos/abstract_recurrence_pattern.rb index 3e5d016d..91276f2e 100644 --- a/app/models/recurring_todos/abstract_recurrence_pattern.rb +++ b/app/models/recurring_todos/abstract_recurrence_pattern.rb @@ -158,13 +158,13 @@ module RecurringTodos def continues_recurring?(previous) return @recurring_todo.occurrences_count < @recurring_todo.number_of_occurrences unless @recurring_todo.number_of_occurrences.nil? - return true if self.end_date.nil? || self.ends_on == 'no_end_date' + return true if end_date.nil? || ends_on == 'no_end_date' - case self.target + case target when 'due_date' - get_due_date(previous) <= self.end_date + get_due_date(previous) <= end_date when 'show_from_date' - get_show_from_date(previous) <= self.end_date + get_show_from_date(previous) <= end_date end end @@ -175,7 +175,7 @@ module RecurringTodos # offset needs to be 1.day for daily patterns or the start will be the # same day as the previous def determine_start(previous, offset = 0.day) - start = self.start_from || NullTime.new + start = start_from || NullTime.new if previous # check if the start_from date is later than previous. If so, use # start_from as start to search for next date diff --git a/app/models/recurring_todos/abstract_recurring_todos_builder.rb b/app/models/recurring_todos/abstract_recurring_todos_builder.rb index 4d39cc54..e3309f27 100644 --- a/app/models/recurring_todos/abstract_recurring_todos_builder.rb +++ b/app/models/recurring_todos/abstract_recurring_todos_builder.rb @@ -60,7 +60,7 @@ module RecurringTodos # get pattern independend attributes filtered_attributes = filter_generic_attributes(attributes) # append pattern specific attributes - attributes_to_filter.each{ |key| filtered_attributes[key]= attributes[key] if attributes.key?(key) } + attributes_to_filter.each { |key| filtered_attributes[key] = attributes[key] if attributes.key?(key) } filtered_attributes end diff --git a/app/models/recurring_todos/daily_recurrence_pattern.rb b/app/models/recurring_todos/daily_recurrence_pattern.rb index 69e2d73f..35a0ea16 100644 --- a/app/models/recurring_todos/daily_recurrence_pattern.rb +++ b/app/models/recurring_todos/daily_recurrence_pattern.rb @@ -36,8 +36,8 @@ module RecurringTodos if only_work_days? # jump over weekend if necessary - return start + 2.day if start.wday() == 6 # saturday - return start + 1.day if start.wday() == 0 # sunday + return start + 2.day if start.wday == 6 # saturday + return start + 1.day if start.wday == 0 # sunday return start else # if there was no previous todo, do not add n: the first todo starts on diff --git a/app/models/recurring_todos/weekly_recurrence_pattern.rb b/app/models/recurring_todos/weekly_recurrence_pattern.rb index c5824d30..5ba3a13f 100644 --- a/app/models/recurring_todos/weekly_recurrence_pattern.rb +++ b/app/models/recurring_todos/weekly_recurrence_pattern.rb @@ -29,7 +29,7 @@ module RecurringTodos def validate super validate_not_blank(every_x_week, "Every other nth week may not be empty for weekly recurrence setting") - something_set = %w{ sunday monday tuesday wednesday thursday friday saturday }.inject(false) { |set, day| set || self.send("on_#{day}") } + something_set = %w{ sunday monday tuesday wednesday thursday friday saturday }.inject(false) { |set, day| set || send("on_#{day}") } errors[:base] << "You must specify at least one day on which the todo recurs" unless something_set end @@ -41,19 +41,19 @@ module RecurringTodos # we did not find anything this week, so check the nth next, starting from # sunday - start = start + self.every_x_week.week - (start.wday).days + start = start + every_x_week.week - (start.wday).days start = find_first_day_in_this_week(start) return start unless start == -1 - raise Exception.new, "unable to find next weekly date (#{self.every_day})" + raise Exception.new, "unable to find next weekly date (#{every_day})" end private def determine_start_date(previous) if previous.nil? - return self.start_from || Time.zone.now + return start_from || Time.zone.now else start = previous + 1.day if start.wday == 0 @@ -61,10 +61,10 @@ module RecurringTodos # that week. Note that we already went into the next week, so -1 start += (every_x_week - 1).week end - unless self.start_from.nil? + unless start_from.nil? # check if the start_from date is later than previous. If so, use # start_from as start to search for next date - start = self.start_from if self.start_from > previous + start = start_from if start_from > previous end return start end diff --git a/app/models/recurring_todos/yearly_recurrence_pattern.rb b/app/models/recurring_todos/yearly_recurrence_pattern.rb index 3c53c6c5..be7df3ba 100644 --- a/app/models/recurring_todos/yearly_recurrence_pattern.rb +++ b/app/models/recurring_todos/yearly_recurrence_pattern.rb @@ -31,7 +31,7 @@ module RecurringTodos end def recurrence_pattern - if self.recurrence_selector == 0 + if recurrence_selector == 0 I18n.t("todos.recurrence.pattern.every_year_on", :date => date_as_month_day) else I18n.t("todos.recurrence.pattern.every_year_on", @@ -94,11 +94,11 @@ module RecurringTodos the_next = start.month > month ? Time.zone.local(start.year + 1, month, 1) : start # get the xth day of the month - the_next = get_xth_day_of_month(self.every_xth_day, day_of_week, month, the_next.year) + the_next = get_xth_day_of_month(every_xth_day, day_of_week, month, the_next.year) # if the_next is before previous, we went back into the past, so try next # year - the_next = get_xth_day_of_month(self.every_xth_day, day_of_week, month, start.year + 1) if the_next <= start + the_next = get_xth_day_of_month(every_xth_day, day_of_week, month, start.year + 1) if the_next <= start the_next end diff --git a/app/models/search/search_results.rb b/app/models/search/search_results.rb index 4db5d59d..d0003efa 100644 --- a/app/models/search/search_results.rb +++ b/app/models/search/search_results.rb @@ -19,33 +19,33 @@ module Search end def number_of_finds - results[:todos].size + results[:projects].size + results[:notes].size + results[:contexts].size + results[:tags].size + results[:todos].size + results[:projects].size + results[:notes].size + results[:contexts].size + results[:tags].size end private def incomplete_todos(terms) - @user.todos. - where("(todos.description " + Common.like_operator + " ? OR todos.notes " + Common.like_operator + " ?) AND todos.completed_at IS NULL", terms, terms) + @user.todos + .where("(todos.description " + Common.like_operator + " ? OR todos.notes " + Common.like_operator + " ?) AND todos.completed_at IS NULL", terms, terms) .includes(Todo::DEFAULT_INCLUDES) .reorder(Arel.sql("todos.due IS NULL, todos.due ASC, todos.created_at ASC")) end def complete_todos(terms) - @user.todos. - where("(todos.description " + Common.like_operator + " ? OR todos.notes " + Common.like_operator + " ?) AND NOT (todos.completed_at IS NULL)", terms, terms) + @user.todos + .where("(todos.description " + Common.like_operator + " ? OR todos.notes " + Common.like_operator + " ?) AND NOT (todos.completed_at IS NULL)", terms, terms) .includes(Todo::DEFAULT_INCLUDES) .reorder("todos.completed_at DESC") end def todo_tags_by_name(terms) - Tagging.find_by_sql([ - "SELECT DISTINCT tags.name as name " + - "FROM tags " + - "LEFT JOIN taggings ON tags.id = taggings.tag_id " + - "LEFT JOIN todos ON taggings.taggable_id = todos.id " + - "WHERE todos.user_id=? " + - "AND tags.name " + Common.like_operator + " ? ", @user.id, terms]) + Tagging.find_by_sql([" + SELECT DISTINCT tags.name as name + FROM tags + LEFT JOIN taggings ON tags.id = taggings.tag_id + LEFT JOIN todos ON taggings.taggable_id = todos.id + WHERE todos.user_id = ? + AND tags.name " + Common.like_operator + " ? ", @user.id, terms]) end end end diff --git a/app/models/stats/actions.rb b/app/models/stats/actions.rb index 6193084a..b9be9de6 100644 --- a/app/models/stats/actions.rb +++ b/app/models/stats/actions.rb @@ -362,7 +362,7 @@ module Stats end def convert_to_weeks_running_array(records, array_size) - return convert_to_array(records, array_size) { |r| [difference_in_weeks(r.completed_at, r.created_at)]} + return convert_to_array(records, array_size) { |r| [difference_in_weeks(r.completed_at, r.created_at)] } end def convert_to_weeks_running_from_today_array(records, array_size) @@ -391,7 +391,7 @@ module Stats def convert_to_cumulative_array(array, max) # calculate fractions - a = Array.new(array.size) {|i| array[i] * 100.0 / max} + a = Array.new(array.size) { |i| array[i] * 100.0 / max } # make cumulative 1.upto(array.size - 1) { |i| a[i] += a[i - 1] } return a @@ -422,7 +422,7 @@ module Stats def compute_running_avg_array(set, upper_bound) result = set_three_month_avg(set, upper_bound) result[upper_bound - 1] = result[upper_bound - 1] * 3 if upper_bound == set.length - result[upper_bound - 2] = result[upper_bound - 2] * 3 / 2 if upper_bound > 1 and upper_bound == set.length + result[upper_bound - 2] = result[upper_bound - 2] * 3 / 2 if upper_bound > 1 && upper_bound == set.length result[0] = "null" result end # unsolved, not triggered, edge case for set.length == upper_bound + 1 diff --git a/app/models/stats/projects.rb b/app/models/stats/projects.rb index 429e68ed..b3d20897 100644 --- a/app/models/stats/projects.rb +++ b/app/models/stats/projects.rb @@ -22,7 +22,7 @@ module Stats def find_top10_longest_running_projects projects = user.projects.order('created_at ASC') - projects.sort_by{ |p| p.running_time }.reverse.take(10) + projects.sort_by { |p| p.running_time }.reverse.take(10) end end end diff --git a/app/models/tag.rb b/app/models/tag.rb index fc3b876e..c3be0e1e 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -9,8 +9,7 @@ class Tag < ApplicationRecord # If database speed becomes an issue, you could remove these validations and # rescue the ActiveRecord database constraint errors instead. - validates_presence_of :name - validates_uniqueness_of :name, :scope => "user_id", :case_sensitive => false + validates :name, presence: true, uniqueness: { :scope => "user_id", :case_sensitive => false } before_create :before_create diff --git a/app/models/tagging.rb b/app/models/tagging.rb index 42513283..617d40d2 100644 --- a/app/models/tagging.rb +++ b/app/models/tagging.rb @@ -8,6 +8,6 @@ class Tagging < ApplicationRecord private def delete_orphaned_tag - tag.destroy if tag and tag.taggings.count == 0 + tag.destroy if tag && tag.taggings.count == 0 end end diff --git a/app/models/todo.rb b/app/models/todo.rb index 043dbbdd..c97f3ade 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -69,7 +69,7 @@ class Todo < ApplicationRecord # state machine include AASM - aasm_initial_state = Proc.new { (self.show_from && self.user && (self.show_from > self.user.date)) ? :deferred : :active } + aasm_initial_state = Proc.new { (show_from && user && (show_from > user.date)) ? :deferred : :active } aasm :column => :state do state :active @@ -100,11 +100,11 @@ class Todo < ApplicationRecord # Description field can't be empty, and must be < 100 bytes Notes must be < # 60,000 bytes (65,000 actually, but I'm being cautious) - validates_presence_of :description - validates_length_of :description, :maximum => MAX_DESCRIPTION_LENGTH - validates_length_of :notes, :maximum => MAX_NOTES_LENGTH, :allow_nil => true - validates_presence_of :show_from, :if => :deferred? - validates_presence_of :context + validates :description, presence: true, length: { maximum: MAX_DESCRIPTION_LENGTH } + validates :notes, length: { maximum: MAX_NOTES_LENGTH, allow_nil: true } + validates :show_from, presence: true, if: :deferred? + validates :context, presence: true + validate :check_show_from_in_future def check_show_from_in_future @@ -139,18 +139,18 @@ class Todo < ApplicationRecord end def not_part_of_hidden_container? - !((self.project && self.project.hidden?) || self.context.hidden?) + !((project && project.hidden?) || context.hidden?) end # Returns a string with description def specification - project_name = self.project.is_a?(NullProject) ? "(none)" : self.project.name - return "\'#{self.description}\' <\'#{self.context.title}\'; \'#{project_name}\'>" + project_name = project.is_a?(NullProject) ? "(none)" : project.name + return "\'#{description}\' <\'#{context.title}\'; \'#{project_name}\'>" end def save_predecessors unless @predecessor_array.nil? # Only save predecessors if they changed - current_array = self.predecessors + current_array = predecessors remove_array = current_array - @predecessor_array add_array = @predecessor_array - current_array @@ -158,13 +158,13 @@ class Todo < ApplicationRecord remove_array.each do |todo| unless todo.nil? @removed_predecessors << todo - self.predecessors.delete(todo) + predecessors.delete(todo) end end add_array.each do |todo| unless todo.nil? - self.predecessors << todo unless self.predecessors.include?(todo) + predecessors << todo unless predecessors.include?(todo) else logger.error "Could not find #{todo.description}" # Unexpected since validation passed end @@ -173,7 +173,7 @@ class Todo < ApplicationRecord end def touch_predecessors - self.touch + touch predecessors.each(&:touch_predecessors) end @@ -183,10 +183,10 @@ class Todo < ApplicationRecord # remove predecessor and activate myself if it was the last predecessor def remove_predecessor(predecessor) - self.predecessors.delete(predecessor) - if self.predecessors.empty? - self.reload # reload predecessors - self.activate! + predecessors.delete(predecessor) + if predecessors.empty? + reload # reload predecessors + activate! else save! end @@ -196,10 +196,10 @@ class Todo < ApplicationRecord def is_successor?(todo) if self == todo return true - elsif self.successors.empty? + elsif successors.empty? return false else - self.successors.each do |item| + successors.each do |item| if item.is_successor?(todo) return true end @@ -213,7 +213,7 @@ class Todo < ApplicationRecord end def hidden? - self.project.hidden? || self.context.hidden? + project.hidden? || context.hidden? end def toggle_completion! @@ -229,7 +229,7 @@ class Todo < ApplicationRecord activate else # parse Date objects into the proper timezone - date = date.in_time_zone.beginning_of_day if (date.is_a? Date) + date = date.in_time_zone.beginning_of_day if date.is_a? Date # show_from needs to be set before state_change because of "bug" in aasm. # If show_from is not set, the todo will not validate and thus aasm will not save @@ -258,14 +258,14 @@ class Todo < ApplicationRecord end def from_recurring_todo? - return self.recurring_todo_id != nil + return recurring_todo_id != nil end def add_predecessor_list(predecessor_list) - return unless predecessor_list.kind_of? String + return unless predecessor_list.is_a? String @predecessor_array = predecessor_list.split(",").inject([]) do |list, todo_id| - predecessor = self.user.todos.find(todo_id.to_i) if todo_id.present? + predecessor = user.todos.find(todo_id.to_i) if todo_id.present? list << predecessor unless predecessor.nil? list end @@ -307,7 +307,7 @@ class Todo < ApplicationRecord # value will be a string. In that case convert to array deps = [deps] unless deps.class == Array - deps.each { |dep| self.add_predecessor(self.user.todos.find(dep.to_i)) if dep.present? } + deps.each { |dep| add_predecessor(user.todos.find(dep.to_i)) if dep.present? } end alias_method :original_context=, :context= @@ -376,7 +376,7 @@ class Todo < ApplicationRecord def destroy # activate successors if they only depend on this action - self.pending_successors.each do |successor| + pending_successors.each do |successor| successor.uncompleted_predecessors.delete(self) if successor.uncompleted_predecessors.empty? successor.activate! diff --git a/app/models/user.rb b/app/models/user.rb index a7fdc43c..c0ebbdb5 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,7 +5,6 @@ class User < ApplicationRecord # Virtual attribute for the unencrypted password attr_accessor :password - #for will_paginate plugin cattr_accessor :per_page @@per_page = 25 @@ -15,11 +14,11 @@ class User < ApplicationRecord end def update_positions(context_ids) - context_ids.each_with_index { |id, position| - context = self.detect { |c| c.id == id.to_i } + context_ids.each_with_index do |id, position| + context = detect { |c| c.id == id.to_i } raise I18n.t('models.user.error_context_not_associated', :context => id, :user => @user.id) if context.nil? context.update_attribute(:position, position + 1) - } + end end end @@ -29,27 +28,27 @@ class User < ApplicationRecord end def update_positions(project_ids) - project_ids.each_with_index { |id, position| - project = self.find_by(id: id.to_i) + project_ids.each_with_index do |id, position| + project = find_by(id: id.to_i) raise I18n.t('models.user.error_project_not_associated', :project => id, :user => @user.id) if project.nil? project.update_attribute(:position, position + 1) - } + end end def projects_in_state_by_position(state) - self.select { |p| p.state == state }.sort_by { |p| p.position } + select { |p| p.state == state }.sort_by { |p| p.position } end def next_from(project) - self.offset_from(project, 1) + offset_from(project, 1) end def previous_from(project) - self.offset_from(project, -1) + offset_from(project, -1) end def offset_from(project, offset) - projects = self.projects_in_state_by_position(project.state) + projects = projects_in_state_by_position(project.state) position = projects.index(project) return nil if position == 0 && offset < 0 projects.at(position + offset) @@ -57,7 +56,7 @@ class User < ApplicationRecord def cache_note_counts project_note_counts = Note.group(:project_id).count - self.each do |project| + each do |project| project.cached_note_count = project_note_counts[project.id] || 0 end end @@ -65,7 +64,7 @@ class User < ApplicationRecord def alphabetize(scope_conditions = {}) projects = where(scope_conditions) projects = projects.sort_by { |project| project.name.downcase } - self.update_positions(projects.map(&:id)) + update_positions(projects.map(&:id)) return projects end @@ -75,7 +74,7 @@ class User < ApplicationRecord todos_in_project.reject { |p| p.todos.active.count > 0 } sorted_project_ids = todos_in_project.map(&:id) - all_project_ids = self.map(&:id) + all_project_ids = map(&:id) other_project_ids = all_project_ids - sorted_project_ids update_positions(sorted_project_ids + other_project_ids) @@ -108,19 +107,19 @@ class User < ApplicationRecord has_one :preference, dependent: :destroy has_many :attachments, through: :todos - validates_presence_of :login - validates_presence_of :password, if: :password_required? - validates_length_of :password, within: 5..72, if: :password_required? - validates_presence_of :password_confirmation, if: :password_required? - validates_confirmation_of :password - validates_length_of :login, within: 3..80 + validates :login, presence: true, length: { within: 3..80 } validates_uniqueness_of :login, on: :create, :case_sensitive => false + validates :password, presence: true, length: { within: 5..72 }, if: :password_required? + validates :password_confirmation, presence: true, if: :password_required? + validates :password, confirmation: true + validates :email, allow_blank: true, format: { with: URI::MailTo::EMAIL_REGEXP } + validate :validate_auth_type - validates :email, :allow_blank => true, format: { with: URI::MailTo::EMAIL_REGEXP } before_create :crypt_password, :generate_token before_update :crypt_password - before_destroy :destroy_dependencies, :delete_taggings, prepend: true # run before deleting todos, projects, contexts, etc. + # Run before deleting todos, projects, contexts, etc. + before_destroy :destroy_dependencies, :delete_taggings, prepend: true def validate_auth_type unless Tracks::Config.auth_schemes.include?(auth_type) @@ -136,8 +135,8 @@ class User < ApplicationRecord return nil if candidate.nil? if Tracks::Config.auth_schemes.include?('database') - return candidate if candidate.auth_type == 'database' and - candidate.password_matches? pass + + return candidate if (candidate.auth_type == 'database' && candidate.password_matches?(pass)) end return nil @@ -177,11 +176,11 @@ class User < ApplicationRecord end def generate_token - self.token = Digest::SHA1.hexdigest "#{Time.now.to_i}#{rand}" + self.token = Digest::SHA1.hexdigest "#{Time.zone.now.to_i}#{rand}" end def remember_token? - remember_token_expires_at && Time.now.utc < remember_token_expires_at + remember_token_expires_at && Time.zone.now.utc < remember_token_expires_at end # These create and unset the fields required for remembering users between browser closes @@ -209,7 +208,7 @@ class User < ApplicationRecord def crypt_password return if password.blank? - write_attribute("crypted_password", self.create_hash(password)) if password == password_confirmation + write_attribute("crypted_password", create_hash(password)) if password == password_confirmation end def password_required? diff --git a/app/services/rich_message_extractor.rb b/app/services/rich_message_extractor.rb index 2e67a94e..f78a3d21 100644 --- a/app/services/rich_message_extractor.rb +++ b/app/services/rich_message_extractor.rb @@ -17,7 +17,7 @@ class RichMessageExtractor DUE_MARKER, TAG_MARKER, STAR_MARKER - ] + ].freeze def initialize(message) @message = message @@ -44,7 +44,7 @@ class RichMessageExtractor # Regex only matches one tag, so recurse until we have them all while string.match /#(.*?)(?=[#{ALL_MARKERS.join}]|\Z)/ tags << sanitize($1) - string.gsub!(/##{$1}/,'') + string.gsub!(/##{$1}/, '') end tags.empty? ? nil : tags end @@ -65,11 +65,11 @@ class RichMessageExtractor private - def select_for symbol + def select_for(symbol) @message.match /#{symbol}(.*?)(?=[#{ALL_MARKERS.join}]|\Z)/ end - def fix_date_string yymmdd + def fix_date_string(yymmdd) "20#{yymmdd[0..1]}-#{yymmdd[2..3]}-#{yymmdd[4..5]} 00:00" end end diff --git a/app/views/integrations/search_plugin.xml.builder b/app/views/integrations/search_plugin.xml.builder index 3468c415..bf6a0e50 100644 --- a/app/views/integrations/search_plugin.xml.builder +++ b/app/views/integrations/search_plugin.xml.builder @@ -1,14 +1,12 @@ xml.instruct! xml.OpenSearchDescription 'xmlns' => "http://a9.com/-/spec/opensearch/1.1/" do - xml.ShortName Tracks xml.Description t('integrations.opensearch_description') xml.InputEncoding 'UTF-8' xml.Image("data:image/x-icon;base64," + @icon_data, - 'width' => '16', 'height' => '16') + 'width' => '16', 'height' => '16') xml.Url 'type' => 'text/html', 'method' => 'GET', - 'template' => url_for(:controller => 'search', :action => 'results', - :only_path => false) + '?search={searchTerms}' + 'template' => url_for(:controller => 'search', :action => 'results', + :only_path => false) + '?search={searchTerms}' end - diff --git a/app/views/projects/index.atom.builder b/app/views/projects/index.atom.builder index e95aedb7..153aaa47 100644 --- a/app/views/projects/index.atom.builder +++ b/app/views/projects/index.atom.builder @@ -9,4 +9,4 @@ atom_feed do |feed| entry.content(project_summary(project), :type => :html) end end -end \ No newline at end of file +end diff --git a/app/views/recurring_todos/_edit_form.html.erb b/app/views/recurring_todos/_edit_form.html.erb index 79d2c8ea..1a91e15a 100644 --- a/app/views/recurring_todos/_edit_form.html.erb +++ b/app/views/recurring_todos/_edit_form.html.erb @@ -11,7 +11,7 @@ text_area_tag( "recurring_todo[notes]", @form_helper.notes, {:cols => 29, :rows => 6}) -%> - " /> + " /> diff --git a/app/views/todos/_new_todo_form.html.erb b/app/views/todos/_new_todo_form.html.erb index aa02e6a6..307a8a18 100644 --- a/app/views/todos/_new_todo_form.html.erb +++ b/app/views/todos/_new_todo_form.html.erb @@ -63,7 +63,7 @@ <%= source_view_tag( @source_view ) %> - <%= hidden_field_tag :_tag_name, @tag_name.underscore.gsub(/\s+/,'_') if source_view_is :tag %> + <%= hidden_field_tag :_tag_name, @tag_name.underscore.gsub(/\s+/, '_') if source_view_is :tag %>