Skip to content

Instantly share code, notes, and snippets.

@addisaden
Last active December 12, 2015 01:38
Show Gist options
  • Save addisaden/4692384 to your computer and use it in GitHub Desktop.
Save addisaden/4692384 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
#encoding: utf-8
require "readline"
require "yaml"
require "drb/drb"
module Todo
class List
def serve
unless @server then
@server = DRb.start_service(nil, self)
end
@server
end
def served
return @server.uri if @server
end
def stop_serve
unless @server.nil? then
@server.stop_service
@server = nil
end
end
attr_reader :name
def initialize(name)
@name = name
@todos = {}
@served = false
end
def todo(todo)
@todos[todo] = false
true
end
def done(todo)
if @todos[todo].nil? then
false
else
@todos[todo] = true
true
end
end
def todos
@todos.keys
end
def to_s
"+ #{ @name }\n" + @todos.collect { |k,v| " - #{ k } (#{ v ? 'done' : 'todo' })" }.join("\n")
end
private
def unserve
unless @served.nil? then
@server.stop_service
@server = nil
@served = nil
end
end
end
class App
def initialize
@lists = []
@remotes = []
@last = nil
end
def start
#
save_file = File.expand_path('todo.yml', Dir.home)
if File.exist?(save_file) && File.file?(save_file) then
@lists = YAML.load(File.read(save_file))
end
#
loop do
begin
prompt = @last.nil? ? '>> ' : "#{ @last.name } >> "
input = Readline::readline(prompt).strip
break if input =~ /^exit$/mi
puts
execute(input)
rescue => e
puts "___ ERROR ___"
puts e
@last = nil
end
end
#
@lists.each { |n| n.stop_serve }
File.open(save_file, 'w') do |f|
f.write(@lists.to_yaml)
end
#
puts "Exits Todo."
end
private
def string_shortener(string)
string.split.collect { |word| word[0] }.join('').downcase
end
def cmd_ls
found = false
errors = []
get_hash_list.each do |shorthand, liste|
begin
puts "#{ shorthand } - #{ liste[:name] }#{ liste[:type] == :remote ? ' (remote)' : ( liste[:object].served ? ' (served on ' + liste[:object].served + ')' : '' ) }"
rescue => e
errors << e
end
found = true
end
puts "Keine Todoliste vorhanden." unless found
puts errors.join("\n\n")
end
def cmd_create_list(name)
@lists << List.new(name)
puts "Liste \"#{ name }\" erstellt."
end
def cmd_cd(shortener)
hash_list = get_hash_list()
if hash_list.keys.include? shortener then
@last = hash_list[shortener][:object]
cmd_show
else
puts "Keine Todoliste mit dem Abkürzung #{ shortener } vorhanden."
end
end
def cmd_show
helper_last_nil do
puts @last
end
end
def cmd_todo(name)
helper_last_nil do
@last.todo(name)
end
cmd_show
end
def cmd_done(name)
helper_last_nil do
if @last.done(name) != true then
puts "#{ name } - konnte nicht als erledigt gekennzeichnet werden."
end
end
cmd_show
end
def cmd_serve()
helper_last_nil do
if @lists.include? @last then
puts "Todo-Liste unter \"#{ @last.serve.uri }\" freigegeben."
else
puts "Remote-Listen können nicht freigegeben werden."
end
end
end
def cmd_connect(url)
@remotes << DRbObject.new_with_uri("druby://#{ url }")
begin
puts @remotes.last
rescue => e
puts e
end
end
def helper_last_nil
begin
if @last.nil? then
puts "Keine Liste ausgewählt. HINT: cd LISTSHORTCUT"
else
yield
end
rescue => e
puts e
end
end
def execute(input)
case
when input =~ /^create\s+\w+/mi
cmd_create_list( get_argument_string(input) )
when input =~ /^ls$/mi
cmd_ls
when input =~ /^cd\s+\w+/mi
cmd_cd get_argument_string(input)
when input =~ /^show$/mi
cmd_show
when input =~ /^todo\s+\w+/mi
cmd_todo( get_argument_string(input) )
when input =~ /^done\s+\w+/mi
cmd_done( get_argument_string(input) )
when input =~ /^serve$/mi
cmd_serve
when input =~ /^connect\s+/mi
cmd_connect( get_argument_string(input) )
else
puts ["ToDo - Hilfe:",
"\n__Allgemein__",
"create NAME - Erstellt eine lokale Todoliste",
"ls - Listet alle Todolisten auf",
"\n__Todo-Listen__",
"cd SHORTCUT - Öffnet eine Todoliste (shortcut sind die Buchstabenkürzel)",
"show - Listet alle Todos der aktuellen Liste auf",
"todo AUFGABE - Erstelle neue Aufgabe in Todoliste oder setze Aufgabe auf unerledigt",
"done AUFGABE - Setze Aufgabe in Todoliste auf erledigt",
"\n__Server_and_Quit__",
"serve - Liste übers Netzwerk freigeben",
"connect IP:PORT - Verbindet zu einer Remote Todoliste",
"exit - Beendet das Programm"
].join("\n ")
puts
end
end
def get_argument_string(input)
input.split[1..-1].join(' ').strip
end
def get_hash_list
lists = {}
lists_local = @lists.collect { |list|
{
name: list.name,
short: string_shortener(list.name),
type: :local,
object: list
}
}.sort { |a,b| a[:name] <=> b[:name] }
lists_remote = @remotes.collect { |list|
begin
{
name: list.name,
short: string_shortener(list.name),
type: :remote,
object: list
}
rescue
@remotes.delete(list)
nil
end
}.select { |n| not n.nil? }.sort { |a,b| a[:name] <=> b[:name] }
[lists_local, lists_remote].each do |part_list|
part_list.each do |list|
if lists.keys.include? list[:short] then
i = 2
loop do
new_short = "#{ list[:short] }#{ i }"
unless lists.keys.include? new_short then
list[:short] = new_short
lists[ new_short ] = list
break
end
i += 1
end
else
lists[ list[:short] ] = list
end
end
end
return lists
end
end
end
Todo::App.new.start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment