potam 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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