potam 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +1 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +52 -0
- data/README.rdoc +6 -0
- data/Rakefile +44 -0
- data/bin/potam +89 -0
- data/db/old.db +0 -0
- data/db/old2.db +0 -0
- data/db/potam.db +0 -0
- data/features/addnote.feature +26 -0
- data/features/addtask.feature +26 -0
- data/features/listtasks.feature +66 -0
- data/features/potam.feature +8 -0
- data/features/report.feature +58 -0
- data/features/step_definitions/potam_steps.rb +43 -0
- data/features/subtasks.feature +31 -0
- data/features/support/env.rb +27 -0
- data/features/taskinfo.feature +128 -0
- data/lib/db.rb +56 -0
- data/lib/dialog.rb +91 -0
- data/lib/notes.rb +3 -0
- data/lib/potam/version.rb +3 -0
- data/lib/potam.rb +9 -0
- data/lib/report.rb +48 -0
- data/lib/subtasks.rb +11 -0
- data/lib/tasks.rb +19 -0
- data/lib/timer.rb +12 -0
- data/potam.gemspec +23 -0
- data/potam.rdoc +5 -0
- data/results.html +480 -0
- data/spec/db_spec.rb +87 -0
- data/spec/notes_spec.rb +68 -0
- data/spec/report_spec.rb +89 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/subtasks_spec.rb +74 -0
- data/spec/tasks_spec.rb +86 -0
- data/spec/timer_spec.rb +31 -0
- data/test/clean.db +0 -0
- data/test/default_test.rb +14 -0
- data/test/test.db +0 -0
- data/test/test_helper.rb +9 -0
- metadata +148 -0
data/lib/db.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'timer'
|
2
|
+
|
3
|
+
class DB
|
4
|
+
|
5
|
+
include Timer
|
6
|
+
|
7
|
+
@@logged = true
|
8
|
+
|
9
|
+
def initialize(db = Sequel.sqlite("#{File.expand_path(File.dirname(__FILE__))}/../db/potam.db"))
|
10
|
+
@db = db
|
11
|
+
table_name = self.class.name.downcase
|
12
|
+
@record_name = table_name[0..-2]
|
13
|
+
self.class.__send__(:attr_reader, "new_#{@record_name}_id")
|
14
|
+
# @db = db
|
15
|
+
# instance_variable_set('@table', db[:"#{table_name}"])
|
16
|
+
@table = @db[:"#{table_name}"]
|
17
|
+
# Sequel.sqlite("#{File.expand_path(File.dirname(__FILE__))}/../test/test.db")
|
18
|
+
# @db = db
|
19
|
+
# @tasks = @db[:tasks]
|
20
|
+
end
|
21
|
+
|
22
|
+
def create(record)
|
23
|
+
record[:created_at] = now if @@logged
|
24
|
+
instance_variable_set("@new_#{@record_name}_id", @table.insert(record))
|
25
|
+
end
|
26
|
+
|
27
|
+
# def create(options = {})
|
28
|
+
# options.each do |key, value|
|
29
|
+
# instance_variable_set("@#{key}", value)
|
30
|
+
# end
|
31
|
+
# @new_task_id = @tasks.insert(title: @title, description: @description, created_at: @created_at)
|
32
|
+
# end
|
33
|
+
|
34
|
+
def last(task_id = false)
|
35
|
+
select_by_task_id(task_id).order(Sequel.desc(:id)).limit(10).all
|
36
|
+
end
|
37
|
+
|
38
|
+
def list(task_id = false)
|
39
|
+
select_by_task_id(task_id).order(Sequel.desc(:id)).all
|
40
|
+
end
|
41
|
+
|
42
|
+
def info(id)
|
43
|
+
@table.where("id = ?", id.to_i).first
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def select_by_task_id(task_id)
|
49
|
+
task_id ? @table.where("task_id = ?", task_id.to_i) : @table
|
50
|
+
end
|
51
|
+
|
52
|
+
# def time
|
53
|
+
# time = ENV['POTAM'] == 'test' ? ENV['POTAMTIME'].to_i : Time.now.to_i
|
54
|
+
# end
|
55
|
+
|
56
|
+
end
|
data/lib/dialog.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'highline/import'
|
2
|
+
require 'unicode'
|
3
|
+
|
4
|
+
module Dialog
|
5
|
+
|
6
|
+
attr_reader :new_task_title, :new_task_description, :new_note_text, :new_subtask_title
|
7
|
+
|
8
|
+
TRANSLATION = {
|
9
|
+
task: 'задача',
|
10
|
+
subtask: 'подзадача',
|
11
|
+
note: 'заметка',
|
12
|
+
created: 'создана',
|
13
|
+
finished: 'завершена'
|
14
|
+
}
|
15
|
+
|
16
|
+
WEEK = [nil, 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс']
|
17
|
+
|
18
|
+
def self.ask_new_task
|
19
|
+
@new_task_title = ask('Введите имя задачи: ')
|
20
|
+
@new_task_description = ask('Введите описание задачи: ')
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.ask_new_subtask
|
24
|
+
@new_subtask_title = ask('Введите подзадачу: ')
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.ask_new_note
|
28
|
+
@new_note_text = ask('Введите текст заметки: ')
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.say_tasks(tasks, indentation = '')
|
32
|
+
tasks.each do |task|
|
33
|
+
id = spaces("##{task[:id]}", 8)
|
34
|
+
title = spaces(task[:title], 41)
|
35
|
+
created_at = ts_to_date(task[:created_at])
|
36
|
+
say("#{indentation}#{id}#{title}#{created_at}")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.say_task(task: task, subtasks: subtasks, notes: notes)
|
41
|
+
say("##{task[:id]} \"#{task[:title]}\"")
|
42
|
+
say(ts_to_date(task[:created_at]))
|
43
|
+
say(task[:description])
|
44
|
+
if subtasks[0]
|
45
|
+
say('Подзадачи:')
|
46
|
+
subtasks.each do |subtask|
|
47
|
+
created_at = ts_to_date(subtask[:created_at])
|
48
|
+
say(" #{created_at} #{subtask[:title]} (##{subtask[:id]})")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
if notes[0]
|
52
|
+
notes.each do |note|
|
53
|
+
say("\n#{ts_to_date(note[:created_at])}")
|
54
|
+
say(note[:text])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.say_report(report)
|
60
|
+
say('Проведена работа по следующим задачам:')
|
61
|
+
self.say_tasks(report[:tasks], ' ')
|
62
|
+
say('=' * 27)
|
63
|
+
report[:tasks].each do |task|
|
64
|
+
say(task[:title] + ':')
|
65
|
+
separator = false
|
66
|
+
report[:events].select{ |event| event[:task_id] == task[:id] }.each do |event|
|
67
|
+
say("\n") if separator
|
68
|
+
separator = true
|
69
|
+
wd = WEEK[ts_to_date(event[:timestamp], "%u").to_i]
|
70
|
+
say(' ' + ts_to_date(event[:timestamp], "%Y-%m-%d (#{wd}) %H:%M:%S"))
|
71
|
+
status = Unicode::capitalize(TRANSLATION[event[:status]])
|
72
|
+
object = TRANSLATION[event[:object]]
|
73
|
+
text = "\"#{event[:text]}\""
|
74
|
+
say(" #{status} #{object} #{text}")
|
75
|
+
end
|
76
|
+
say('-' * 27)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def spaces(text, width)
|
83
|
+
spaces = ' ' * (width - text.length)
|
84
|
+
return "#{text}#{spaces}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def ts_to_date(timestamp, template = "%Y-%m-%d")
|
88
|
+
Time.at(timestamp.to_i).strftime(template)
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
data/lib/notes.rb
ADDED
data/lib/potam.rb
ADDED
data/lib/report.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'timer'
|
2
|
+
|
3
|
+
class Report
|
4
|
+
|
5
|
+
include Timer
|
6
|
+
|
7
|
+
def initialize(db = Sequel.sqlite("#{File.expand_path(File.dirname(__FILE__))}/../db/potam.db"))
|
8
|
+
@db = db
|
9
|
+
@report = Hash.new
|
10
|
+
@report[:events] = Array.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def week
|
14
|
+
@report[:tasks] = @db.fetch("SELECT * FROM tasks
|
15
|
+
WHERE (created_at BETWEEN #{last_mon} AND #{now})
|
16
|
+
OR id IN (SELECT task_id FROM subtasks WHERE (created_at BETWEEN #{last_mon} AND #{now})
|
17
|
+
OR (finished_at BETWEEN #{last_mon} AND #{now}))
|
18
|
+
OR id IN (SELECT task_id FROM notes WHERE (created_at BETWEEN #{last_mon} AND #{now}))
|
19
|
+
ORDER BY id DESC").to_a
|
20
|
+
order = Array.new
|
21
|
+
@report[:tasks].each{ |task| order << task[:id] }
|
22
|
+
@report[:tasks].select{ |task| task[:created_at].between?(last_mon, now) }.each{ |task| to_event(task) }
|
23
|
+
@db[:notes].where("created_at BETWEEN #{last_mon} AND #{now}").all.each{ |note| to_event(note) }
|
24
|
+
@db[:subtasks].where("created_at BETWEEN #{last_mon} AND #{now}").all.each{ |subtask| to_event(subtask) }
|
25
|
+
@db[:subtasks].where("finished_at BETWEEN #{last_mon} AND #{now}").all.each{ |subtask| to_event(subtask, :finished) }
|
26
|
+
@report[:events].sort_by!{ |event| [order.index(event[:task_id]), event[:timestamp]] }
|
27
|
+
return @report
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def to_event(object, status = :created)
|
33
|
+
if object[:description]
|
34
|
+
@report[:events] <<
|
35
|
+
{object: :task, status: :created, task_id: object[:id],
|
36
|
+
text: object[:title], timestamp: object[:created_at]}
|
37
|
+
elsif object[:text]
|
38
|
+
@report[:events] <<
|
39
|
+
{object: :note, status: :created, task_id: object[:task_id],
|
40
|
+
text: object[:text], timestamp: object[:created_at]}
|
41
|
+
else
|
42
|
+
@report[:events] <<
|
43
|
+
{object: :subtask, status: status, task_id: object[:task_id],
|
44
|
+
text: object[:title], timestamp: object[:"#{status}_at"]}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/lib/subtasks.rb
ADDED
data/lib/tasks.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
class Tasks < DB
|
2
|
+
|
3
|
+
def last
|
4
|
+
@db.fetch("SELECT * FROM tasks AS T ORDER BY (SELECT MAX(ts) FROM
|
5
|
+
(SELECT notes.created_at AS ts FROM notes WHERE task_id = T.id
|
6
|
+
UNION SELECT subtasks.created_at AS ts FROM subtasks WHERE task_id = T.id
|
7
|
+
UNION SELECT subtasks.finished_at AS ts FROM subtasks WHERE task_id = T.id
|
8
|
+
UNION SELECT tasks.created_at AS ts FROM tasks WHERE id = T.id)) DESC LIMIT 0, 10;").to_a
|
9
|
+
end
|
10
|
+
|
11
|
+
def list
|
12
|
+
@db.fetch("SELECT * FROM tasks AS T ORDER BY (SELECT MAX(ts) FROM
|
13
|
+
(SELECT notes.created_at AS ts FROM notes WHERE task_id = T.id
|
14
|
+
UNION SELECT subtasks.created_at AS ts FROM subtasks WHERE task_id = T.id
|
15
|
+
UNION SELECT subtasks.finished_at AS ts FROM subtasks WHERE task_id = T.id
|
16
|
+
UNION SELECT tasks.created_at AS ts FROM tasks WHERE id = T.id)) DESC;").to_a
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/lib/timer.rb
ADDED
data/potam.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Ensure we require the local version and not one we might have installed already
|
2
|
+
require File.join([File.dirname(__FILE__),'lib','potam','version.rb'])
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = 'potam'
|
5
|
+
s.version = Potam::VERSION
|
6
|
+
s.author = 'Michael'
|
7
|
+
s.email = '0x22aa2@gmail.com'
|
8
|
+
# s.homepage = 'http://your.website.com'
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.summary = 'Personal Offline TAsk Manager - POTAM'
|
11
|
+
s.files = `git ls-files`.split("
|
12
|
+
")
|
13
|
+
s.require_paths << 'lib'
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.extra_rdoc_files = ['README.rdoc','potam.rdoc']
|
16
|
+
s.rdoc_options << '--title' << 'potam' << '--main' << 'README.rdoc' << '-ri'
|
17
|
+
s.bindir = 'bin'
|
18
|
+
s.executables << 'potam'
|
19
|
+
s.add_development_dependency('rake')
|
20
|
+
s.add_development_dependency('rdoc')
|
21
|
+
s.add_development_dependency('aruba')
|
22
|
+
s.add_runtime_dependency('gli','2.12.2')
|
23
|
+
end
|