Skip to content

Instantly share code, notes, and snippets.

@kdwinter
Created March 9, 2009 14:52
Show Gist options
  • Save kdwinter/76335 to your computer and use it in GitHub Desktop.
Save kdwinter/76335 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby19
# encoding: utf-8
=begin
Author: Gigamo <gigamo@gmail.com>
Inspired by Todo.txt (http://www.todotxt.com)
Usage: rudo <action> [<action arguments>]
* rudo add <some text>
* rudo del <tasknumber>
* rudo done <tasknumber>
* rudo append <tasknumber> [<some text to append>]
* rudo replace <tasknumber> [<some text to replace>]
* rudo list [<match>]
=end
module Rudo
extend self
# File that stores the todo items.
@todo_file = ENV["HOME"] + '/.todotxt/todo.txt'
# Main method.
def run
# Check if @todo_file exists, exit if not.
die "[+] #@todo_file doesn't exist" unless File.exists? @todo_file
# Create a new Todo instance
todo = Todo.new(@todo_file)
# Parse commandline input.
case ARGV.shift
when 'add'
todo.add(ARGV.join(' ')) unless ARGV.nil?
when 'rm', 'del', 'delete'
todo.delete(ARGV.shift.to_i) if ARGV.length == 1
when 'append'
todo.append(ARGV.shift.to_i, ARGV.join(' ')) unless ARGV.length < 1
when 'mv', 'replace'
todo.replace(ARGV.shift.to_i, ARGV.join(' ')) unless ARGV.length < 1
when 'ls', 'list'
ARGV.nil? ? todo.list : todo.list(ARGV)
else
$stdout.puts help
end
end
class Todo
attr_reader :file
def initialize(file)
@file = file
end
def add(text)
# Add a new task to @todo_file.
File.open(self.file, 'a') { |file| file.puts text }
end
def append(item, text='')
# Append text to an existing task.
tasks = get_tasks
Rudo.die "[+] #{item}: No such todo." unless tasks.has_key? item
tasks[item] = [tasks[item], text].join(' ')
write_tasks tasks
end
def replace(item, text)
# Replace text in a given task.
tasks = get_tasks
Rudo.die "[+] #{item}: No such todo." unless tasks.has_key? item
tasks[item] = text
write_tasks tasks
end
def delete(item)
# Delete a task by given tasknumber.
tasks = get_tasks
Rudo.die "[+] #{item}: No such todo." unless tasks.has_key? item
$stdout.puts "Delete `#{tasks[item]}' [y/n]?"
case $stdin.gets.chomp
when 'y', 'yes', 'yeah', 'yup', 'yep'
tasks.delete(item)
end
write_tasks tasks
end
def list(patterns=nil)
# Print a list of all tasks found in @todo_file.
# Optionally accept arguments, match arguments for
# items in the list, and print only matching items.
items = []
tasks = get_tasks
if patterns
tasks.each do |key, value|
match = true
patterns.each { |pattern| match = false unless value[/#{pattern}/i] }
items << " #{key}: #{value}" if match
end
else
tasks.each { |key, value| items << " #{key}: #{value}" }
end
items.sort.each { |item| $stdout.puts item }
end
private
def get_tasks
# Get a hash of tasks from @todo_file.
count = 0
tasks = {}
File.open(self.file).each_line do |line|
next if line.strip == ''
count += 1
tasks[count] = line.chomp
end.close
return tasks
end
def write_tasks(task_dict)
# Write a dictionary of tasks to @todo_file.
keys = task_dict.keys.sort
File.open(self.file, 'w') do |file|
keys.each { |key| file.puts task_dict[key] }
end
end
end
def die(text)
# Print error and exit.
$stderr.puts text
exit 1
end
private
def help
# Return usage located in the comments above.
return "Usage: " + File.read(__FILE__).match(/Usage:(.+?)=end/m)[1].strip.gsub(/rudo/, File.basename($0))
end
end
Rudo.run if $0 == __FILE__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment