#!/usr/bin/env ruby require 'rubygems' require 'neverdone' require 'clamp' require 'everton' require 'term/ansicolor' require 'highline/import' class String include Term::ANSIColor end # # Task Title Conventions # s: = state (done,starred) # r: = reminder (date_hour, format: 20110101_HHMM, hour optional) # l: = list (list name, multiple todo list support) # HACK, FIXME, BAD, SHIT: Ignore SSL warnings class Net::HTTP alias_method :old_initialize, :initialize def initialize(*args) old_initialize(*args) @ssl_context = OpenSSL::SSL::SSLContext.new @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE end end class NeverdoneCommand < Clamp::Command def execute begin authenticate @notebook = Everton::Notebook.find('Neverdone Todo') rescue Evernote::EDAM::Error::EDAMSystemException #token expired authenticate force=true @notebook = Everton::Notebook.find('Neverdone Todo') rescue Evernote::EDAM::Error::EDAMUserException #token expired authenticate force=true @notebook = Everton::Notebook.find('Neverdone Todo') end if not @notebook print "Neverdone Todo notebook not found, creating..." @notebook = Everton::Notebook.create('Neverdone Todo') puts ' Done' end lazy_execute end def authenticate(force=false) @config = Neverdone::Config.load auth = { :user_store_url => @config[:user_store_url], :consumer_key => Neverdone::CONSUMER_KEY, :consumer_secret => Neverdone::CONSUMER_SECRET, :access_token => @config[:access_token] } if not @config[:username] auth[:username] = ask("Evernote username: ") else auth[:username] = @config[:username] end if not @config[:password] auth[:password] = ask("Evernote password: ") { |q| q.echo = false } puts "\nConfiguration stored at #{ENV['HOME']}/.neverdone.conf\n\n" else auth[:password] = @config[:password] end Everton::Remote.authenticate auth, force @config[:access_token] = Everton::Remote.access_token @config[:username] = auth[:username] @config[:password] = auth[:password] @config.save end end class TasksCommand < NeverdoneCommand option "--all", :flag, "Show completed tasks" def lazy_execute count = 0 notes = [] if all? notes = @notebook.find_notes else notes = @notebook.find_notes("-intitle:s:done") end notes.sort! { |a,b| if a.title =~ /s:done/; -1; else 1;end} notes.each do |n| title = n.title count += 1 flags = [] if title =~ /(s:done)/ flags << "s:done".green.bold title.gsub!($1, '') end if title =~ /(l:\w+)/ flags << $1.white.bold title.gsub!(/(l:\w+)/, '') end if flags.size > 0 puts "#{count}. #{title.ljust(40)} [#{flags.join(',')}]" else puts "#{count}. #{title}" end end end end class AddCommand < NeverdoneCommand parameter "TITLE ...", "Task title", :attribute_name => "title" option ["-n", "--note"], "TEXT ...", "Task text", :default => '' option ["-l", "--list"], "LIST", "List to add the task to" def lazy_execute text = '' if not text t = title.join(' ') if list @notebook.add_note("#{t} l:#{list.gsub(' ', '_')}", text) else @notebook.add_note(t, text) end end end class CheckCommand < NeverdoneCommand parameter "NUMBER", "Task number" def lazy_execute count = 0 @notebook.find_notes("-intitle:s:done").reverse.each do |n| count += 1 if count == number.to_i n.title = n.title + ' s:done' n.update end end end end class VersionCommand < NeverdoneCommand option "--version", :flag, "print version" def lazy_execute puts Neverdone::VERSION end end class Driver < Clamp::Command option "--version", :flag, "print version" do puts "Neverdone Version " + ::Neverdone::VERSION exit end option "--all", :flag, "Print completed tasks also" do TasksCommand.run(File.basename($0), ['--all']) exit end default_subcommand "tasks", "Print pending tasks", TasksCommand subcommand "add", "Add new task", AddCommand subcommand "check", "Complete task", CheckCommand end Driver.run