mirror of
https://github.com/TracksApp/tracks.git
synced 2025-09-22 05:50:47 +02:00
commit
33f4963a02
14 changed files with 132 additions and 179 deletions
73
Gemfile
73
Gemfile
|
@ -1,55 +1,41 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'rails', '~> 6.0.3'
|
||||
gem 'sassc-rails', '~> 2.1.2'
|
||||
gem 'coffee-rails', '~> 5.0.0'
|
||||
|
||||
#gem 'json'
|
||||
|
||||
# todo: remove xml api
|
||||
gem 'actionpack-xml_parser', '~> 2.0'
|
||||
gem 'activemodel-serializers-xml', '~> 1.0.1'
|
||||
|
||||
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
||||
gem 'therubyracer', group: :therubyracer
|
||||
|
||||
gem 'uglifier', '>=1.3.0'
|
||||
gem 'coffee-rails', '~> 5.0.0'
|
||||
|
||||
gem 'jquery-rails', '~> 4.4'
|
||||
gem 'jquery-ui-rails', '~>6.0.1'
|
||||
|
||||
# you may comment out the database driver(s) you will not be using.
|
||||
# This will prevent a native build of the driver. Building native drivers is not
|
||||
# always possible on all platforms
|
||||
# Alternatively use --without <group> arguments to bundler to not install that group
|
||||
gem 'sqlite3', group: :sqlite
|
||||
gem 'mysql2', '~> 0.5.3', group: :mysql
|
||||
gem 'pg', '~> 1.2.3', group: :postgresql
|
||||
|
||||
gem 'RedCloth'
|
||||
gem 'sanitize', '~> 5.2'
|
||||
gem 'will_paginate'
|
||||
gem 'acts_as_list'
|
||||
gem 'aasm', '~> 5.1.1'
|
||||
gem 'htmlentities'
|
||||
gem 'rails_autolink'
|
||||
gem 'puma', '~> 5.0'
|
||||
gem 'paperclip'
|
||||
|
||||
# To use ActiveModel has_secure_password
|
||||
gem 'bcrypt', '~> 3.1.16'
|
||||
|
||||
gem 'chartjs-ror', :git => 'git://github.com/ZeiP/chartjs-ror.git'
|
||||
|
||||
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
|
||||
# gem 'turbolinks'
|
||||
|
||||
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
|
||||
# gem 'jbuilder', '~> 1.2'
|
||||
gem 'rails', '~> 6.0.3'
|
||||
gem 'sassc-rails', '~> 2.1.2'
|
||||
|
||||
gem 'bootstrap-sass', '3.4.1'
|
||||
gem 'font-awesome-sass', '~> 5.15.1'
|
||||
|
||||
gem 'uglifier', '>=1.3.0'
|
||||
|
||||
gem 'aasm', '~> 5.1.1'
|
||||
gem 'acts_as_list'
|
||||
gem 'bcrypt', '~> 3.1.16'
|
||||
gem 'chartjs-ror', :git => 'git://github.com/ZeiP/chartjs-ror.git'
|
||||
gem 'htmlentities'
|
||||
gem 'paperclip'
|
||||
gem 'puma', '~> 5.0'
|
||||
gem 'rails_autolink'
|
||||
gem 'RedCloth'
|
||||
gem 'sanitize', '~> 5.2'
|
||||
gem 'will_paginate'
|
||||
|
||||
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
||||
gem 'therubyracer', group: :therubyracer
|
||||
|
||||
# Use --without <group> argument to skip unnecessary drivers
|
||||
gem 'sqlite3', group: :sqlite
|
||||
gem 'mysql2', '~> 0.5.3', group: :mysql
|
||||
gem 'pg', '~> 1.2.3', group: :postgresql
|
||||
|
||||
group :development do
|
||||
gem 'spring'
|
||||
gem 'yard'
|
||||
|
@ -79,15 +65,6 @@ group :test do
|
|||
gem 'mocha', :require => false
|
||||
gem 'minitest-stub-const'
|
||||
|
||||
gem 'selenium-webdriver', '~> 3.142'
|
||||
|
||||
# uncomment to use the webkit option. This depends on Qt being installed
|
||||
# gem 'capybara-webkit'
|
||||
|
||||
# uncomment to be able to make screenshots from scenarios
|
||||
#gem 'capybara-screenshot'
|
||||
#gem 'launchy'
|
||||
|
||||
gem 'simplecov'
|
||||
# get test coverage info on codeclimate
|
||||
gem 'codeclimate-test-reporter', '1.0.7', group: :test, require: nil
|
||||
|
|
|
@ -89,7 +89,6 @@ GEM
|
|||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.11)
|
||||
byebug (11.1.3)
|
||||
childprocess (3.0.0)
|
||||
climate_control (0.2.0)
|
||||
codeclimate-test-reporter (1.0.7)
|
||||
simplecov
|
||||
|
@ -245,7 +244,6 @@ GEM
|
|||
rubocop-ast (0.8.0)
|
||||
parser (>= 2.7.1.5)
|
||||
ruby-progressbar (1.10.1)
|
||||
rubyzip (2.3.0)
|
||||
safe_yaml (1.0.5)
|
||||
sanitize (5.2.1)
|
||||
crass (~> 1.0.2)
|
||||
|
@ -259,9 +257,6 @@ GEM
|
|||
sprockets (> 3.0)
|
||||
sprockets-rails
|
||||
tilt
|
||||
selenium-webdriver (3.142.7)
|
||||
childprocess (>= 0.5, < 4.0)
|
||||
rubyzip (>= 1.2.2)
|
||||
simplecov (0.19.1)
|
||||
docile (~> 1.1)
|
||||
simplecov-html (~> 0.11)
|
||||
|
@ -355,7 +350,6 @@ DEPENDENCIES
|
|||
rubocop (~> 0.93)
|
||||
sanitize (~> 5.2)
|
||||
sassc-rails (~> 2.1.2)
|
||||
selenium-webdriver (~> 3.142)
|
||||
simplecov
|
||||
solargraph
|
||||
spring
|
||||
|
|
|
@ -24,8 +24,8 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def set_locale
|
||||
locale = params[:locale] # specifying a locale in the request takes precedence
|
||||
locale = locale || prefs.locale unless current_user.nil? # otherwise, the locale of the currently logged in user takes over
|
||||
locale = locale || request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first if request.env['HTTP_ACCEPT_LANGUAGE']
|
||||
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)
|
||||
I18n.locale = locale
|
||||
|
@ -43,13 +43,14 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# Get expiry time (allow ten seconds window for the case where we have
|
||||
# none)
|
||||
expiry_time = session['expiry_time'] || Time.now + 10
|
||||
if expiry_time < Time.now
|
||||
now = Time.zone.now
|
||||
expiry_time = session['expiry_time'] || now + 10
|
||||
if expiry_time < now
|
||||
# Too late, matey... bang goes your session!
|
||||
reset_session
|
||||
else
|
||||
# Okay, you get another hour
|
||||
session['expiry_time'] = Time.now + (60*60)
|
||||
session['expiry_time'] = now + (60*60)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -13,15 +13,9 @@ class CalendarController < ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
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.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 })] ) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -110,13 +110,13 @@ class ContextsController < ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.xml {
|
||||
format.xml do
|
||||
if @saved
|
||||
render :xml => @context.to_xml(:except => :user_id)
|
||||
else
|
||||
render :body => "Error on update: #{@context.errors.full_messages.inject("") { |v, e| v + e + " " }}", :status => 409
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class ProjectsController < ApplicationController
|
|||
@projects_to_review = projects.select { |p| p.needs_review?(current_user) }
|
||||
@stalled_projects = projects.select { |p| p.stalled? }
|
||||
@blocked_projects = projects.select { |p| p.blocked? }
|
||||
@current_projects = projects.uncompleted.select { |p| not (p.needs_review?(current_user)) }.sort_by { |p| p.last_reviewed || Time.zone.at(0) }
|
||||
@current_projects = projects.uncompleted.select { |p| not p.needs_review?(current_user) }.sort_by { |p| p.last_reviewed || Time.zone.at(0) }
|
||||
|
||||
init_not_done_counts(['project'])
|
||||
init_hidden_todo_counts(['project'])
|
||||
|
@ -112,11 +112,11 @@ class ProjectsController < ApplicationController
|
|||
def projects_and_actions
|
||||
@projects = current_user.projects.active
|
||||
respond_to do |format|
|
||||
format.text {
|
||||
format.text do
|
||||
# somehow passing Mime[:text] using content_type to render does not work
|
||||
headers['Content-Type'] = Mime[:text].to_s
|
||||
render :action => 'index_text_projects_and_actions', :layout => false, :content_type => Mime[:text]
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -246,15 +246,14 @@ class ProjectsController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.js { render :template => template }
|
||||
format.html { redirect_to :action => 'index'}
|
||||
format.xml {
|
||||
format.xml do
|
||||
if @saved
|
||||
render :xml => @project.to_xml(:except => :user_id)
|
||||
else
|
||||
render :body => "Error on update: #{@project.errors.full_messages.inject("") { |v, e| v + e + " " }}", :status => 409
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
|
@ -268,10 +267,10 @@ class ProjectsController < ApplicationController
|
|||
@project.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.js {
|
||||
format.js do
|
||||
@down_count = current_user.projects.size
|
||||
update_state_counts
|
||||
}
|
||||
end
|
||||
format.xml { render :body => "Deleted project #{@project.name}" }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -703,7 +703,7 @@ class TodosController < ApplicationController
|
|||
def tags
|
||||
tags_beginning = current_user.tags.where(Tag.arel_table[:name].matches("#{params[:term]}%"))
|
||||
tags_all = current_user.tags.where(Tag.arel_table[:name].matches("%#{params[:term]}%"))
|
||||
tags_all = tags_all - tags_beginning
|
||||
tags_all -= tags_beginning
|
||||
|
||||
respond_to do |format|
|
||||
format.autocomplete { render :body => for_autocomplete(tags_beginning+tags_all, params[:term]) }
|
||||
|
@ -731,30 +731,26 @@ class TodosController < ApplicationController
|
|||
determine_down_count
|
||||
determine_remaining_in_container_count(@todo)
|
||||
source_view do |page|
|
||||
page.project {
|
||||
page.project do
|
||||
@remaining_undone_in_project = current_user.projects.find(@todo.project_id).todos.not_completed.count
|
||||
}
|
||||
page.tag {
|
||||
determine_deferred_tag_count(params['_tag_name'])
|
||||
}
|
||||
end
|
||||
page.tag { determine_deferred_tag_count(params['_tag_name']) }
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.js { render :action => 'update' }
|
||||
format.m {
|
||||
format.m do
|
||||
notify(:notice, t("todos.action_deferred", :description => @todo.description))
|
||||
do_mobile_todo_redirection
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
|
@ -801,12 +797,8 @@ class TodosController < ApplicationController
|
|||
@todo = current_user.todos.find(params['id'])
|
||||
@return_path = cookies[:mobile_url] ? cookies[:mobile_url] : mobile_path
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
redirect_to home_path, "Viewing note of todo is not implemented"
|
||||
}
|
||||
format.m {
|
||||
render :action => "show_notes"
|
||||
}
|
||||
format.html { redirect_to home_path, "Viewing note of todo is not implemented" }
|
||||
format.m { render :action => "show_notes" }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -868,7 +860,7 @@ class TodosController < ApplicationController
|
|||
i = 1
|
||||
while params['and' + i.to_s]
|
||||
@tag_expr << params['and' + i.to_s].split(',')
|
||||
i=i+1
|
||||
i += 1
|
||||
end
|
||||
|
||||
@single_tag = @tag_expr.size == 1 && @tag_expr[0].size == 1
|
||||
|
@ -986,17 +978,17 @@ end
|
|||
|
||||
def determine_remaining_in_container_count(todo = @todo)
|
||||
source_view do |from|
|
||||
from.deferred {
|
||||
from.deferred do
|
||||
todos_in_container, todos_in_target_container = find_todos_in_container_and_target_container(todo, @todo)
|
||||
@remaining_in_context = todos_in_container.deferred_or_blocked.count
|
||||
@target_context_count = todos_in_target_container.deferred_or_blocked.count
|
||||
}
|
||||
from.todo {
|
||||
end
|
||||
from.todo do
|
||||
todos_in_container, todos_in_target_container = find_todos_in_container_and_target_container(todo, @todo)
|
||||
@remaining_in_context = todos_in_container.active.not_hidden.count
|
||||
@target_context_count = todos_in_target_container.active.not_hidden.count
|
||||
}
|
||||
from.tag {
|
||||
end
|
||||
from.tag do
|
||||
tag = Tag.where(:name => params['_tag_name']).first
|
||||
tag = Tag.new(:name => params['tag']) if tag.nil?
|
||||
|
||||
|
@ -1006,8 +998,8 @@ end
|
|||
@target_context_count = todos_in_target_container.active.not_hidden.with_tag(tag.id).count
|
||||
@remaining_hidden_count = current_user.todos.hidden.with_tag(tag.id).count
|
||||
@remaining_deferred_or_pending_count = current_user.todos.with_tag(tag.id).deferred_or_blocked.count
|
||||
}
|
||||
from.project {
|
||||
end
|
||||
from.project do
|
||||
project_id = @project_changed ? @original_item.project_id : @todo.project_id
|
||||
@remaining_deferred_or_pending_count = current_user.projects.find(project_id).todos.deferred_or_blocked.count
|
||||
|
||||
|
@ -1018,11 +1010,11 @@ end
|
|||
end
|
||||
|
||||
@target_context_count = current_user.projects.find(project_id).todos.active.count
|
||||
}
|
||||
from.calendar {
|
||||
end
|
||||
from.calendar do
|
||||
@target_context_count = @new_due_id.blank? ? 0 : count_old_due_empty(@new_due_id)
|
||||
}
|
||||
from.context {
|
||||
end
|
||||
from.context do
|
||||
context = current_user.contexts.find(todo.context_id)
|
||||
@remaining_deferred_or_pending_count = context.todos.deferred_or_blocked.count
|
||||
|
||||
|
@ -1037,13 +1029,11 @@ end
|
|||
actions_in_target = @todo.context.todos.deferred_or_blocked
|
||||
end
|
||||
@target_context_count = actions_in_target.count
|
||||
}
|
||||
from.done {
|
||||
end
|
||||
from.done do
|
||||
@remaining_in_context = DoneTodos.remaining_in_container(current_user.todos, @original_completed_period)
|
||||
}
|
||||
from.all_done {
|
||||
@remaining_in_context = current_user.todos.completed.count
|
||||
}
|
||||
end
|
||||
from.all_done { @remaining_in_context = current_user.todos.completed.count }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@ class RichMessageExtractor
|
|||
include ActionView::Helpers::SanitizeHelper
|
||||
extend ActionView::Helpers::SanitizeHelper::ClassMethods
|
||||
|
||||
PROJECT_MARKER = '~'
|
||||
CONTEXT_MARKER = '@'
|
||||
TICKLER_MARKER = '>'
|
||||
DUE_MARKER = '<'
|
||||
TAG_MARKER = '#'
|
||||
STAR_MARKER = '*'
|
||||
PROJECT_MARKER = '~'.freeze
|
||||
CONTEXT_MARKER = '@'.freeze
|
||||
TICKLER_MARKER = '>'.freeze
|
||||
DUE_MARKER = '<'.freeze
|
||||
TAG_MARKER = '#'.freeze
|
||||
STAR_MARKER = '*'.freeze
|
||||
|
||||
ALL_MARKERS = [
|
||||
PROJECT_MARKER,
|
||||
|
|
|
@ -73,7 +73,6 @@ require 'readline'
|
|||
require File.expand_path(File.dirname(__FILE__) + '/tracks_cli/tracks_api')
|
||||
|
||||
class TemplateParser
|
||||
|
||||
def initialize
|
||||
@keywords = {}
|
||||
end
|
||||
|
@ -92,7 +91,7 @@ class TemplateParser
|
|||
options = {}
|
||||
|
||||
# first char is . or ^ the latter meaning this todo is dependent on the previous one
|
||||
options[:depend]= line[0].chr == "^" ? true : false;
|
||||
options[:depend] = line[0].chr == "^"
|
||||
line = line[1..line.length] # remove first char
|
||||
|
||||
tmp = line.split("|")
|
||||
|
@ -143,11 +142,9 @@ class TemplateParser
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class TemplatePoster
|
||||
|
||||
def initialize(options)
|
||||
@options = options
|
||||
@tracks = TracksCli::TracksAPI.new({
|
||||
|
@ -209,11 +206,13 @@ class TemplatePoster
|
|||
|
||||
return resp.code == '200'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Error < StandardError; end
|
||||
class InvalidParser < StandardError; end
|
||||
class Error < StandardError
|
||||
end
|
||||
|
||||
class InvalidParser < StandardError
|
||||
end
|
||||
|
||||
class ConsoleOptionsForTemplate
|
||||
attr_reader :parser, :options, :keywords
|
||||
|
|
|
@ -12,11 +12,11 @@ module LoginSystem
|
|||
# Logout the {#current_user} and redirect to login page
|
||||
#
|
||||
# @param [String] message notification to display
|
||||
def logout_user message=t('login.logged_out')
|
||||
def logout_user(message=t('login.logged_out'))
|
||||
@user.forget_me if logged_in?
|
||||
cookies.delete :auth_token
|
||||
session['user_id'] = nil
|
||||
if ( SITE_CONFIG['authentication_schemes'].include? 'cas') && session[:cas_user]
|
||||
if SITE_CONFIG['authentication_schemes'].include?('cas') && session[:cas_user]
|
||||
CASClient::Frameworks::Rails::Filter.logout(self)
|
||||
else
|
||||
reset_session
|
||||
|
@ -78,7 +78,7 @@ module LoginSystem
|
|||
end
|
||||
# Allow also login based on auth data
|
||||
auth = get_basic_auth_data
|
||||
if user = User.where(:login => auth[:user], :token => auth[:pass]).first
|
||||
if (user = User.where(:login => auth[:user], :token => auth[:pass]).first)
|
||||
set_current_user(user)
|
||||
return true
|
||||
end
|
||||
|
@ -102,12 +102,12 @@ module LoginSystem
|
|||
|
||||
login_from_cookie
|
||||
|
||||
if session['user_id'] and authorize?(get_current_user)
|
||||
if session['user_id'] && authorize?(get_current_user)
|
||||
return true
|
||||
end
|
||||
|
||||
auth = get_basic_auth_data
|
||||
if user = User.authenticate(auth[:user], auth[:pass])
|
||||
if (user = User.authenticate(auth[:user], auth[:pass]))
|
||||
session['user_id'] = user.id
|
||||
set_current_user(user)
|
||||
return true
|
||||
|
@ -125,12 +125,12 @@ module LoginSystem
|
|||
def login_optional
|
||||
login_from_cookie
|
||||
|
||||
if session['user_id'] and authorize?(get_current_user)
|
||||
if session['user_id'] && authorize?(get_current_user)
|
||||
return true
|
||||
end
|
||||
|
||||
auth = get_basic_auth_data
|
||||
if user = User.authenticate(auth[:user], auth[:pass])
|
||||
if (user = User.authenticate(auth[:user], auth[:pass]))
|
||||
session['user_id'] = user.id
|
||||
set_current_user(user)
|
||||
return true
|
||||
|
@ -197,7 +197,7 @@ module LoginSystem
|
|||
authdata = request.env[location].to_s.split
|
||||
end
|
||||
end
|
||||
if authdata and authdata[0] == 'Basic'
|
||||
if authdata && authdata[0] == 'Basic'
|
||||
data = Base64.decode64(authdata[1]).split(':')[0..1]
|
||||
{
|
||||
user: data[0],
|
||||
|
|
|
@ -25,4 +25,3 @@ namespace :tracks do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue