diff --git a/Gemfile b/Gemfile index f6553fd1..f014403c 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,7 @@ gem "mysql2" gem "highline", "~>1.5.0" gem "RedCloth" +gem "formatize" gem "sanitize", "~>1.2.1" gem "will_paginate" gem "acts_as_list", "~>0.1.4" diff --git a/Gemfile.lock b/Gemfile.lock index 5059bc4c..39cfc5b8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -33,6 +33,7 @@ GEM acts_as_list (0.1.5) arel (3.0.2) bcrypt-ruby (3.0.1) + bluecloth (2.2.0) builder (3.0.0) coffee-rails (3.2.2) coffee-script (>= 2.2.0) @@ -45,6 +46,10 @@ GEM erubis (2.7.0) execjs (1.3.0) multi_json (~> 1.0) + formatize (1.1.0) + RedCloth (~> 4.2) + actionpack (~> 3.0) + bluecloth (~> 2.2) gem_plugin (0.2.3) highline (1.5.2) hike (1.2.1) @@ -131,6 +136,7 @@ DEPENDENCIES acts_as_list (~> 0.1.4) bcrypt-ruby (~> 3.0.0) coffee-rails (~> 3.2.1) + formatize highline (~> 1.5.0) htmlentities (~> 4.3.0) jquery-rails diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f898a16c..eec99129 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -9,7 +9,6 @@ class ApplicationController < ActionController::Base protect_from_forgery - helper :application include LoginSystem helper_method :current_user, :prefs, :format_date, :markdown @@ -143,14 +142,6 @@ class ApplicationController < ActionController::Base return json_elems end - # Uses RedCloth to transform text using either Textile or Markdown Need to - # require redcloth above RedCloth 3.0 or greater is needed to use Markdown, - # otherwise it only handles Textile - # - def markdown(text) - RedCloth.new(text).to_html - end - # Here's the concept behind this "mobile content negotiation" hack: In # addition to the main, AJAXy Web UI, Tracks has a lightweight low-feature # 'mobile' version designed to be suitablef or use from a phone or PDA. It @@ -223,7 +214,7 @@ class ApplicationController < ActionController::Base def redirect_back_or_home respond_to do |format| - format.html { redirect_back_or_default home_url } + format.html { redirect_back_or_default root_url } format.m { redirect_back_or_default mobile_url } end end diff --git a/app/controllers/integrations_controller.rb b/app/controllers/integrations_controller.rb index 9daaa5ec..36e5e052 100644 --- a/app/controllers/integrations_controller.rb +++ b/app/controllers/integrations_controller.rb @@ -53,7 +53,7 @@ class IntegrationsController < ApplicationController message = Mail.new(params[:message]) # find user - user = User.where("preferences.sms_email = ?", message.from).includes(:preferences).first + user = User.where("preferences.sms_email = ?", message.from).includes(:preference).first if user.nil? render :text => "No user found", :status => 404 return false diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb index 9aa3b83e..d65af5d5 100644 --- a/app/controllers/login_controller.rb +++ b/app/controllers/login_controller.rb @@ -27,15 +27,13 @@ class LoginController < ApplicationController @username = session[:cas_user] @login_url = CASClient::Frameworks::Rails::Filter.login_url(self) end - if openid_enabled? && using_open_id? - login_openid - elsif cas_enabled? && session[:cas_user] + if cas_enabled? && session[:cas_user] login_cas else @page_title = "TRACKS::Login" cookies[:preferred_auth] = prefered_auth? unless cookies[:preferred_auth] case request.method - when :post + when 'POST' if @user = User.authenticate(params['user_login'], params['user_password']) session['user_id'] = @user.id # If checkbox on login page checked, we don't expire the session after 1 hour @@ -54,7 +52,7 @@ class LoginController < ApplicationController @login = params['user_login'] notify :warning, t('login.unsuccessful') end - when :get + when 'GET' if User.no_users_yet? redirect_to signup_path return diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 243fe2ee..06ad7edc 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -9,7 +9,6 @@ class ProjectsController < ApplicationController def index @source_view = params['_source_view'] || 'project_list' - @new_project = current_user.projects.build if params[:projects_and_actions] projects_and_actions else @@ -19,15 +18,22 @@ class ProjectsController < ApplicationController if params[:only_active_with_no_next_actions] @projects = current_user.projects.active.select { |p| count_undone_todos(p) == 0 } else - @projects = current_user.projects + @projects = current_user.projects.all end + @new_project = current_user.projects.build respond_to do |format| format.html &render_projects_html format.m &render_projects_mobile format.xml { render :xml => @projects.to_xml( :except => :user_id ) } - format.rss &render_rss_feed - format.atom &render_atom_feed - format.text &render_text_feed + format.rss do + @feed_title = I18n.t('models.project.feed_title') + @feed_description = I18n.t('models.project.feed_description', :username => current_user.display_name) + end + format.atom do + @feed_title = I18n.t('models.project.feed_title') + @feed_description = I18n.t('models.project.feed_description', :username => current_user.display_name) + end + format.text format.autocomplete &render_autocomplete end end @@ -144,16 +150,9 @@ class ProjectsController < ApplicationController render_failure "Expected post format is valid xml like so: project name." return end - - @project = current_user.projects.build - params_are_invalid = true - if (params['project'] || (params['request'] && params['request']['project'])) - @project.attributes = params['project'] || params['request']['project'] - params_are_invalid = false - end + @project = current_user.projects.build(params['project']) @go_to_project = params['go_to_project'] @saved = @project.save - @project_not_done_counts = { @project.id => 0 } @active_projects_count = current_user.projects.active.count @contexts = current_user.contexts @@ -161,9 +160,7 @@ class ProjectsController < ApplicationController respond_to do |format| format.js { @down_count = current_user.projects.size } format.xml do - if @project.new_record? && params_are_invalid - render_failure "Expected post format is valid xml like so: project name." - elsif @project.new_record? + if @project.new_record? render_failure @project.errors.full_messages.join(', ') else head :created, :location => project_url(@project), :text => @project.id @@ -350,33 +347,6 @@ class ProjectsController < ApplicationController render :action => 'project_mobile' end end - - def render_rss_feed - lambda do - render_rss_feed_for @projects, :feed => feed_options, - :title => :name, - :item => { :description => lambda { |p| @template.summary(p) } } - end - end - - def render_atom_feed - lambda do - render_atom_feed_for @projects, :feed => feed_options, - :item => { :description => lambda { |p| @template.summary(p) }, - :title => :name, - :author => lambda { |p| nil } } - end - end - - def feed_options - Project.feed_options(current_user) - end - - def render_text_feed - lambda do - render :action => 'index', :layout => false, :content_type => Mime::TEXT - end - end def render_autocomplete lambda do diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 89b403c9..d1f9dd51 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -75,9 +75,9 @@ module ProjectsHelper project_description = '' project_description += Tracks::Utils.render_text( project.description ) unless project.description.blank? project_description += content_tag(:p, - "#{count_undone_todos_phrase(p)}. " + t('projects.project_state', :state => project.state) + "#{count_undone_todos_phrase(p)}. #{t('projects.project_state', :state => project.state)}".html_safe ) - project_description + raw project_description end def needsreview_class(item) diff --git a/app/models/project.rb b/app/models/project.rb index c9a845cc..d877dbcc 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -47,13 +47,6 @@ class Project < ActiveRecord::Base NullProject.new end - def self.feed_options(user) - { - :title => I18n.t('models.project.feed_title'), - :description => I18n.t('models.project.feed_description', :username => user.display_name) - } - end - def hide_todos todos.each do |t| unless t.completed? || t.deferred? diff --git a/app/views/integrations/_applescript1.rhtml b/app/views/integrations/_applescript1.html.erb similarity index 90% rename from app/views/integrations/_applescript1.rhtml rename to app/views/integrations/_applescript1.html.erb index a0a2e14f..1e6497d5 100644 --- a/app/views/integrations/_applescript1.rhtml +++ b/app/views/integrations/_applescript1.html.erb @@ -6,13 +6,13 @@ set myUsername to "<%= current_user.login %>" set myToken to "<%= current_user.token %>" set myContextID to <%= context.id %> (* <%= context.name %> *) --- Display dialog to enter your description +-- Display dialog to enter your description display dialog "<%= t('integrations.applescript_next_action_prompt') %>" default answer "" set myDesc to text returned of the result -- Now send all that info to Tracks -- Edit the URL of your Tracks installation if necessary" -tell application "<%= home_url %>backend/api" +tell application "<%= root_url %>backend/api" set returnValue to call xmlrpc {method name:"NewTodo", parameters:{myUsername, myToken, myContextID, myDesc}} end tell diff --git a/app/views/integrations/_applescript2.rhtml b/app/views/integrations/_applescript2.html.erb similarity index 88% rename from app/views/integrations/_applescript2.rhtml rename to app/views/integrations/_applescript2.html.erb index ba18d42d..7eb014bb 100644 --- a/app/views/integrations/_applescript2.rhtml +++ b/app/views/integrations/_applescript2.html.erb @@ -1,10 +1,10 @@ -(* +(* Script to grab the sender and subject of the selected Mail message(s), and create new next action(s) with description "Email [sender] about [subject]" If you have Growl, it pops a notification up with the id of -the newly created action. +the newly created action. *) (* Edit appropriately for your setup *) @@ -50,25 +50,25 @@ on importMessage(theMessage) -- Now send all that info to Tracks -- Edit the URL of your Tracks installation if necessary" - tell application "<%= home_url %>backend/api" + tell application "<%= root_url %>backend/api" set returnValue to call xmlrpc {method name:"NewTodo", parameters:{myUsername, myToken, myContextID, myDesc, myNote}} end tell - (* Growl support - comment out or delete this section if + (* Growl support - comment out or delete this section if you don't have Growl *) tell application "GrowlHelperApp" set the allNotificationsList to ¬ {"Tracks Notification"} - -- Make a list of the notifications - -- that will be enabled by default. - -- Those not enabled by default can be enabled later + -- Make a list of the notifications + -- that will be enabled by default. + -- Those not enabled by default can be enabled later -- in the 'Applications' tab of the growl prefpane. set the enabledNotificationsList to ¬ {"Tracks Notification"} -- Register our script with growl. - -- You can optionally (as here) set a default icon + -- You can optionally (as here) set a default icon -- for this script's notifications. register as application ¬ "Tracks Applescript" all notifications allNotificationsList ¬ diff --git a/app/views/integrations/_quicksilver_applescript.rhtml b/app/views/integrations/_quicksilver_applescript.html.erb similarity index 91% rename from app/views/integrations/_quicksilver_applescript.rhtml rename to app/views/integrations/_quicksilver_applescript.html.erb index 35db68db..59a0e285 100644 --- a/app/views/integrations/_quicksilver_applescript.rhtml +++ b/app/views/integrations/_quicksilver_applescript.html.erb @@ -5,7 +5,7 @@ using terms from application "Quicksilver" set myToken to "<%= current_user.token %>" set myContextID to <%= context.id %> (* <%= context.name %> *) - tell application "<%= home_url %>backend/api" + tell application "<%= root_url %>backend/api" set returnValue to call xmlrpc {method name:"NewTodo", parameters:{myUsername, myToken, myContextID, ThisClipping}} end tell tell application "Quicksilver" diff --git a/app/views/integrations/google_gadget.erb b/app/views/integrations/google_gadget.erb index f9e93562..45ca5554 100644 --- a/app/views/integrations/google_gadget.erb +++ b/app/views/integrations/google_gadget.erb @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/views/integrations/index.de.html.erb b/app/views/integrations/index.de.html.erb index 52f812e9..3f701411 100644 --- a/app/views/integrations/index.de.html.erb +++ b/app/views/integrations/index.de.html.erb @@ -90,7 +90,7 @@

If you enter the following entry to your crontab, you will receive email every day around 5 AM with a list of the upcoming actions which are due within the next 7 days.

- +

You can of course use other text <%= link_to 'feeds provided by Tracks', feeds_path %> -- why not email a list of next actions in a particular project to a group of colleagues who are working on the project?

@@ -100,7 +100,7 @@ If Tracks is running on the same server as your mail server, you can use the integrated mail handler built into tracks. Steps to set it up:


-

Do you have one of your own to add? +

Do you have one of your own to add? Tell us about it in our Tips and Tricks forum and we may include it on this page in a future versions of Tracks.

@@ -90,7 +90,7 @@

If you enter the following entry to your crontab, you will receive email every day around 5 AM with a list of the upcoming actions which are due within the next 7 days.

- +

You can of course use other text <%= link_to 'feeds provided by Tracks', feeds_path %> -- why not email a list of next actions in a particular project to a group of colleagues who are working on the project?

@@ -100,7 +100,7 @@ If Tracks is running on the same server as your mail server, you can use the integrated mail handler built into tracks. Steps to set it up: