potam 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,3 @@
1
+ class Notes < DB
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ module Potam
2
+ VERSION = '0.0.1'
3
+ end
data/lib/potam.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'potam/version.rb'
2
+ require 'db'
3
+ require 'tasks'
4
+ require 'notes'
5
+ require 'dialog'
6
+ require 'subtasks'
7
+ require 'report'
8
+ require 'sequel'
9
+ require 'gli'
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
@@ -0,0 +1,11 @@
1
+ class Subtasks < DB
2
+
3
+ def finish!(id)
4
+ @table.where("id = ?", id.to_i).update(status: 1, finished_at: now)
5
+ end
6
+
7
+ def active(task_id)
8
+ @table.where("task_id = ?", task_id.to_i).where("status = ?", 0).order(Sequel.desc(:id)).all
9
+ end
10
+
11
+ end
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
@@ -0,0 +1,12 @@
1
+ module Timer
2
+
3
+ def now
4
+ time = ENV['POTAM'] == 'test' ? ENV['POTAMTIME'].to_i : Time.now.to_i
5
+ end
6
+
7
+ def last_mon
8
+ mon = Time.at(now - (Time.at(now).wday - 1) * 24 * 60 * 60)
9
+ Time.new(mon.year, mon.month, mon.day).to_i
10
+ end
11
+
12
+ end
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
data/potam.rdoc ADDED
@@ -0,0 +1,5 @@
1
+ = potam
2
+
3
+ Generate this with
4
+ potam rdoc
5
+ After you have described your command line interface