Created
October 8, 2012 01:22
-
-
Save michaelminter/3850248 to your computer and use it in GitHub Desktop.
Mac command line note management tool
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env ruby | |
| require 'json' | |
| require 'time' | |
| class Time | |
| module Units | |
| Second = 1 | |
| Minute = Second * 60 | |
| Hour = Minute * 60 | |
| Day = Hour * 24 | |
| Week = Day * 7 | |
| Month = Week * 4 | |
| Year = Day * 365 | |
| Decade = Year * 10 | |
| Century = Decade * 10 | |
| Millennium = Century * 10 | |
| Eon = 1.0/0 | |
| end | |
| def time_ago_in_words | |
| time_difference = Time.now.utc.to_i - self.to_i | |
| unit = get_unit(time_difference) | |
| unit_difference = time_difference / Units.const_get(unit.capitalize) | |
| unit = unit.to_s.downcase + ('s' if time_difference > 1) | |
| "#{unit_difference} #{unit} ago" | |
| end | |
| private | |
| def get_unit(time_difference) | |
| Units.constants.each_cons(2) do |con| | |
| return con.first if (Units.const_get(con[0])...Units.const_get(con[1])) === time_difference | |
| end | |
| end | |
| end | |
| txtblk='\e[0;30m' # Black - Regular | |
| txtred='\e[0;31m' # Red | |
| txtgrn='\e[0;32m' # Green | |
| txtylw='\e[0;33m' # Yellow | |
| txtblu='\e[0;34m' # Blue | |
| txtpur='\e[0;35m' # Purple | |
| txtcyn='\e[0;36m' # Cyan | |
| txtwht='\e[0;37m' # White | |
| bldblk='\e[1;30m' # Black - Bold | |
| bldred='\e[1;31m' # Red | |
| bldgrn='\e[1;32m' # Green | |
| bldylw='\e[1;33m' # Yellow | |
| bldblu='\e[1;34m' # Blue | |
| bldpur='\e[1;35m' # Purple | |
| bldcyn='\e[1;36m' # Cyan | |
| bldwht='\e[1;37m' # White | |
| unkblk='\e[4;30m' # Black - Underline | |
| undred='\e[4;31m' # Red | |
| undgrn='\e[4;32m' # Green | |
| undylw='\e[4;33m' # Yellow | |
| undblu='\e[4;34m' # Blue | |
| undpur='\e[4;35m' # Purple | |
| undcyn='\e[4;36m' # Cyan | |
| undwht='\e[4;37m' # White | |
| bakblk='\e[40m' # Black - Background | |
| bakred='\e[41m' # Red | |
| bakgrn='\e[42m' # Green | |
| bakylw='\e[43m' # Yellow | |
| bakblu='\e[44m' # Blue | |
| bakpur='\e[45m' # Purple | |
| bakcyn='\e[46m' # Cyan | |
| bakwht='\e[47m' # White | |
| txtrst='\e[0m' # Text Reset | |
| def colorize(text, color_code) | |
| "\e[#{color_code}m#{text}\e[0m" | |
| end | |
| def colorize_topic(text, topic) | |
| color_code = case topic | |
| when '!'; then '1;31'; | |
| when 'todo'; then '0;32'; | |
| when 'reminder'; then '0;33'; | |
| when 'work'; then '0;31'; | |
| when 'home','shopping'; then '0;36'; | |
| when 'gift'; then '0;35'; | |
| end | |
| "\e[#{color_code}m#{text}\e[0m" | |
| end | |
| @version = '1.0' | |
| @user = `whoami`.gsub(/\n/, '') | |
| @time = Time.now.utc | |
| @args = ARGV | |
| @datafile = "/Users/#{@user}/.notes" | |
| @notes = JSON.parse(open(@datafile, 'rb').read) rescue [] | |
| # Helpers | |
| def see_usage | |
| puts %{ | |
| NAME | |
| notes - Mac command line note management tool | |
| SYNOPSIS | |
| n [options] [message] | |
| DESCRIPTION | |
| Saves notes data as JSON in ~/.notes | |
| VERSION | |
| 1.0 | |
| GLOBAL OPTIONS | |
| -b, --backup store datafile in AWS cloud | |
| -c, --clear clears notes datafile | |
| -C, --CLEAR clears (hard) notes datafile | |
| -d int delete line number | |
| -D int delete (hard) line number | |
| -h, --help show the help message and exit | |
| -l, --list print details for each note | |
| -n, --new create new note (not mandatory) | |
| -r, --restore restore datafile from AWS cloud | |
| -s, --sort sort by topic, message, id | |
| -t, --topic create topic for new note | |
| -v, --verbose print status message for new note | |
| --version show version and exit | |
| EXAMPLE | |
| n -v 'hello world' | |
| DEPENDENCIES | |
| Ruby 1.9, JSON (Ruby?), whoami (sys) | |
| TODO | |
| Test usability for Linux operating systems | |
| CREATED BY | |
| Michael Minter <http://michaelminter.github.com> | |
| SPECIAL THANKS | |
| * https://github.com/Sirupsen/time-ago-in-words | |
| } | |
| exit | |
| end | |
| def save_data(data) | |
| (data = data.to_json) if data.class.to_s == 'Array' | |
| open(@datafile, 'w') { |f| f.puts data } | |
| end | |
| def confirm(message="Are you sure? [Yn] ") | |
| print message | |
| STDOUT.flush | |
| return $stdin.gets.chomp | |
| end | |
| def delete_line(verbose=true) | |
| delete_id = @args.last.to_i | |
| newdata = [] | |
| capture = {} | |
| incount = 1 | |
| @notes.each_with_index do |note, index| | |
| if note['id'] == delete_id | |
| capture = note | |
| else | |
| newdata << { :id => incount, :message => note['message'], :topic => note['topic'], :time => note['time'] } | |
| incount = incount + 1 | |
| end | |
| end | |
| save_data(newdata) | |
| puts colorize("Deleted note: #{capture['message']}", '0;32') | |
| exit | |
| end | |
| def notes_table | |
| id_greatest_numerable = 'id'.length | |
| messages_greatest_numerable = 'message'.length | |
| topics_greatest_numberable = 'topic'.length | |
| @notes.each do |note| | |
| id_greatest_numerable = note['id'].to_s.length > id_greatest_numerable ? note['id'].to_s.length : id_greatest_numerable | |
| messages_greatest_numerable = note['message'].length > messages_greatest_numerable ? note['message'].length : messages_greatest_numerable | |
| topics_greatest_numberable = note['topic'].length > topics_greatest_numberable ? note['topic'].length : topics_greatest_numberable | |
| end | |
| puts colorize("#{'ID'.ljust(id_greatest_numerable+2, ' ')} #{'Message'.ljust(messages_greatest_numerable+2, ' ')} #{'Topic'.ljust(topics_greatest_numberable+2, ' ')} Time ago", '1;37') | |
| @notes.each do |note| | |
| note_id = "[#{note['id']}]" | |
| print "#{note_id.ljust(id_greatest_numerable+2, ' ')} " | |
| print "#{note['message'].ljust(messages_greatest_numerable+2, ' ')} " | |
| print colorize_topic("#{note['topic'].ljust(topics_greatest_numberable+2, ' ')} ", note['topic']) | |
| print "#{Time.parse(note['time']).time_ago_in_words}\n" | |
| end | |
| end | |
| def list_notes(mode='short') | |
| if @args[0] == '-l' || mode == 'list' | |
| notes_table | |
| else | |
| @notes.each_with_index do |note, index| | |
| puts "* #{note['message']}" | |
| end | |
| end | |
| exit | |
| end | |
| def create_note(verbose=false) | |
| message = @args.last.strip | |
| topic = message[/^([a-zA-Z0-9 !-_]+):|^!/, 1].nil? ? '' : message[/^([a-zA-Z0-9 !-_]+):|^!/, 1].strip | |
| if @notes.empty? | |
| @notes << { :id => 1, :message => message, :topic => topic, :time => @time } | |
| else | |
| last_id = @notes.last['id'] | |
| next_id = last_id + 1 | |
| @notes << { :id => next_id, :message => message, :topic => topic, :time => @time } | |
| end | |
| save_data(@notes) | |
| puts colorize(message, '0;32') if (@args.include?('-v') || @args.include?('--verbose')) | |
| exit | |
| end | |
| def clear_file() | |
| File.open(@datafile, 'w') { |file| file.truncate(0) } | |
| end | |
| # Application | |
| if @args.empty? | |
| list_notes | |
| end | |
| unless @args.grep(/^-+\w+/).empty? | |
| case @args[0] | |
| when '-h', '--help' | |
| see_usage | |
| when "--version" | |
| puts @version; exit | |
| when '-c', '--clear' | |
| if confirm == 'Y' | |
| clear_file | |
| exit | |
| else | |
| puts colorize("Nothing happened", '0;31') | |
| exit | |
| end | |
| when '-C', '--CLEAR' | |
| clear_file | |
| exit | |
| when '-d', '--delete' | |
| if confirm == 'Y' | |
| delete_line | |
| else | |
| puts colorize("Nothing happened", '0;31') | |
| exit | |
| end | |
| when '-D' ,'--DELETE' | |
| delete_line | |
| when '-l' | |
| list_notes('list') | |
| when '-v', '--verbose' | |
| if @args.count > 1 | |
| create_note | |
| else | |
| see_usage | |
| end | |
| when 'n', '--new' | |
| create_note | |
| else | |
| see_usage | |
| end | |
| else | |
| create_note | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment