wlog 0.0.3 → 1.0.0

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gemfile +1 -0
  4. data/README.md +72 -3
  5. data/Rakefile +31 -0
  6. data/bin/wlog +12 -6
  7. data/lib/wlog.rb +0 -1
  8. data/lib/wlog/commands/commandable.rb +9 -0
  9. data/lib/wlog/commands/concat_description.rb +21 -0
  10. data/lib/wlog/commands/innit_db.rb +22 -0
  11. data/lib/wlog/commands/make_csv.rb +24 -0
  12. data/lib/wlog/commands/new_entry.rb +16 -0
  13. data/lib/wlog/commands/replace_pattern.rb +21 -0
  14. data/lib/wlog/db_registry.rb +19 -31
  15. data/lib/wlog/domain/ansi_colors.rb +15 -0
  16. data/lib/wlog/domain/attachment.rb +80 -0
  17. data/lib/wlog/domain/helpers.rb +42 -0
  18. data/lib/wlog/domain/issue.rb +100 -0
  19. data/lib/wlog/domain/key_value.rb +55 -0
  20. data/lib/wlog/domain/log_entry.rb +100 -0
  21. data/lib/wlog/domain/sql_modules/attachment_sql.rb +21 -0
  22. data/lib/wlog/domain/sql_modules/issue_sql.rb +28 -0
  23. data/lib/wlog/domain/sql_modules/key_value_sql.rb +20 -0
  24. data/lib/wlog/domain/sql_modules/log_entry_sql.rb +35 -0
  25. data/lib/wlog/domain/sql_modules/polymorphic_attachments_sql.rb +24 -0
  26. data/lib/wlog/domain/static_configurations.rb +24 -0
  27. data/lib/wlog/domain/sys_config.rb +23 -0
  28. data/lib/wlog/sql/mono/1.sql +50 -0
  29. data/lib/wlog/sql/seq/.gitkeep +0 -0
  30. data/lib/wlog/ui/cli_interface.rb +152 -0
  31. data/lib/wlog/ui/commands/attach_to_issue.rb +0 -0
  32. data/lib/wlog/ui/commands/attach_to_log_entry.rb +11 -0
  33. data/lib/wlog/ui/commands/create_issue.rb +18 -0
  34. data/lib/wlog/ui/commands/ui_command.rb +9 -0
  35. data/lib/wlog/ui/issue_ui.rb +126 -0
  36. data/lib/wlog/version.rb +1 -1
  37. data/spec/key_vale_spec.rb +9 -0
  38. data/wlog.gemspec +6 -2
  39. metadata +61 -8
  40. data/lib/wlog/cli_interface.rb +0 -149
  41. data/lib/wlog/helpers.rb +0 -28
  42. data/lib/wlog/log_entry.rb +0 -102
  43. data/lib/wlog/static_configurations.rb +0 -21
@@ -0,0 +1,42 @@
1
+ require 'wlog/domain/static_configurations'
2
+
3
+ module Wlog
4
+ # This contains a few helper methods that may be used by any part in the
5
+ # application.
6
+ # @author Simon Symeonidis
7
+ class Helpers
8
+ include StaticConfigurations
9
+ # Break the string to a different line
10
+ # @param string is the string that we want processed.
11
+ # @param numchars is the amount of characters max per line.
12
+ def self.break_string(string,numchars)
13
+ desc , cl = "", 0
14
+ string.split.each do |word|
15
+ wlength = word.length
16
+ if cl + wlength + 1 > numchars
17
+ cl = 0
18
+ desc.concat($/)
19
+ end
20
+ desc.concat(word).concat(" ")
21
+ cl += wlength + 1
22
+ end
23
+ desc.chomp!
24
+ desc end
25
+
26
+ # Check to see if the database exists in the DataDirectory
27
+ # @return true if exists, otherwise false
28
+ def self.database_exits?
29
+ File.exists? "#{DataDirectory}#{ARGV[0] || DefaultDb}"
30
+ end
31
+
32
+ # Check to see if DataDirectory exists
33
+ # Create the data directory if it does not exist.
34
+ def self.make_dirs!
35
+ # Does the data dir path not exist?
36
+ unless File.exists? DataDirectory
37
+ FileUtils.mkdir_p DataDirectory
38
+ end
39
+ nil end
40
+ end
41
+ end # module Wlog
42
+
@@ -0,0 +1,100 @@
1
+ require 'wlog/db_registry'
2
+ require 'wlog/domain/sql_modules/issue_sql'
3
+ require 'wlog/domain/log_entry'
4
+
5
+ module Wlog
6
+ # This aggregates log entries. The total time spent on this issue is
7
+ # calculated from checking out said log entries.
8
+ # @author Simon Symeonidis
9
+ class Issue
10
+ include IssueSql
11
+
12
+ def initialize
13
+ @reported_date = Time.now
14
+ @log_entries = Array.new
15
+ @status = 0
16
+ end
17
+
18
+ def self.find(id)
19
+ issue = Issue.new
20
+ ret = DbRegistry.instance.execute(SelectSql, id).first
21
+ issue.quick_assign! ret
22
+ issue end
23
+
24
+ def self.find_all
25
+ arr = Array.new
26
+ DbRegistry.instance.execute(SelectAllSql).each do |row|
27
+ issue = Issue.new
28
+ issue.quick_assign! row
29
+ arr.push issue
30
+ end
31
+ arr end
32
+
33
+ def self.delete(id); DbRegistry.instance.execute(DeleteSql, id) end
34
+
35
+ def insert
36
+ DbRegistry.instance
37
+ .execute(InsertSql, @description,
38
+ @reported_date.to_i, @due_date.to_i, @status)
39
+ end
40
+
41
+ def delete; DbRegistry.instance.execute(DeleteSql, @id) end
42
+
43
+ def update
44
+ DbRegistry.instance
45
+ .execute(UpdateSql, @description, @reported_date.to_i,
46
+ @due_date.to_i, @status, @id)
47
+ end
48
+
49
+ # Add a log entry object to the issue
50
+ def add_log_entry(le)
51
+ @log_entries.push le
52
+ end
53
+
54
+ def quick_assign!(row)
55
+ @id, @description, @reported_date, @due_date , @status =\
56
+ row[0], row[1], Time.at(row[2]), Time.at(row[3]), row[4]
57
+ nil end
58
+
59
+ def to_s
60
+ "+ Issue ##{@id}#{$/}"\
61
+ " - Reported : #{@reported_date}#{$/}"\
62
+ " - Due : #{@due_date}#{$/}"\
63
+ " - Entries : #{@log_entries.count}#{$/}"\
64
+ " - Status : "\
65
+ "#{$/}"\
66
+ " - #{@description}"
67
+ end
68
+
69
+ def mark_started!; @status = 0 end
70
+ def mark_working!; @status = 1 end
71
+ def mark_finished!; @status = 2 end
72
+ def status_s; Statuses[@status] end
73
+
74
+ # [String] Description of the issue at hand
75
+ attr_accessor :description
76
+
77
+ # [Time] The due date of the issue
78
+ attr_accessor :due_date
79
+
80
+ # [Time] The reported date of the issue
81
+ attr_accessor :reported_date
82
+
83
+ # [Array<LogEntry>] an array containing the log entries that are specific
84
+ # to this issue
85
+ attr_accessor :log_entries
86
+
87
+ # [Fixnum] is the identifier of this object
88
+ attr_accessor :id
89
+
90
+ # [Fixnum] Status of the current issue (0 is for not started, 1 working on,
91
+ # 2 for finished)
92
+ attr_accessor :status
93
+
94
+ private
95
+
96
+ Statuses = {0 => "new", 1 => "started work", 2 => "finished"}
97
+
98
+ end # class Issue
99
+ end # module Wlog
100
+
@@ -0,0 +1,55 @@
1
+ require 'wlog/db_registry'
2
+ require 'wlog/domain/sql_modules/key_value_sql'
3
+ module Wlog
4
+ # An active record that stores keys with values. Keys and values are strings.
5
+ # convert as you need them.
6
+ #
7
+ # Note the behaviour on this; it's exactly like a ruby hash, so if you store
8
+ # a string 'jon' as a key with value '12', and then you store 'jon' with value
9
+ # '42', when looking up 'jon' you will retrieve only the latter (42).
10
+ #
11
+ # @author Simon Symeonidis
12
+ class KeyValue
13
+ include KeyValueSql
14
+
15
+ # Insert a key in the storage. If exists, replace the value with new one
16
+ # @return nil
17
+ def self.put!(key, value)
18
+ if self.get(key).nil?
19
+ self.create!(key, value)
20
+ else
21
+ self.update(key, value)
22
+ end
23
+ nil end
24
+
25
+ # Get a certain value by key
26
+ # @return the value given the key. nil if not found
27
+ def self.get(key)
28
+ ret = DbRegistry.instance.execute(Select, key)
29
+ ret = ret.empty? ? nil : ret.first
30
+ end
31
+
32
+ # destroy by key
33
+ def self.destroy!(key)
34
+ DbRegistry.instance.execute(DeleteSql, key)
35
+ nil end
36
+
37
+ private
38
+
39
+ # We want to provide a simple interface to the kv store, so the user should
40
+ # not really care about updates
41
+ def self.update(key,value)
42
+ DbRegistry.instance.execute(UpdateSql, value, key)
43
+ end
44
+
45
+ # Create a pair... ;)
46
+ def self.create!(key, value)
47
+ DbRegistry.instance.execute(InsertSql, key, value)
48
+ end
49
+
50
+ class << self
51
+ private :new, :allocate
52
+ end
53
+ end
54
+ end # module Wlog
55
+
@@ -0,0 +1,100 @@
1
+ require 'wlog/db_registry'
2
+ require 'wlog/domain/helpers'
3
+ require 'wlog/domain/attachment'
4
+ require 'wlog/domain/sql_modules/log_entry_sql'
5
+
6
+ module Wlog
7
+ # Author :: Simon Symeonidis
8
+ # Active Record Domain object for a log entry
9
+ class LogEntry
10
+ include LogEntrySql
11
+
12
+ def initialize
13
+ @date = Time.new
14
+ end
15
+
16
+ def self.find(id)
17
+ row = DbRegistry.instance.execute(Select,id).first
18
+ le = LogEntry.new
19
+ le.quick_assign!(row[0], row[1], Time.at(row[2]))
20
+ le end
21
+
22
+ def self.find_all
23
+ self.generic_find_all(SelectAll)
24
+ end
25
+
26
+ def self.find_all_by_issue_id(id)
27
+ self.generic_find_all(SelectAllByIssue, id)
28
+ end
29
+
30
+ # Delete a log entry with a given id.
31
+ # @example Simple usage
32
+ # # Since this is a class method:
33
+ # LogEntry.delete(12)
34
+ def self.delete(id)
35
+ DbRegistry.instance.execute(DeleteSql,id)
36
+ end
37
+
38
+ # update the entry
39
+ def update
40
+ DbRegistry.instance.execute(UpdateSql,@description,@id)
41
+ end
42
+
43
+ # Search by string to find a matching description with 'LIKE'.
44
+ def self.search_descriptions(term)
45
+ all = Array.new
46
+ DbRegistry.instance.execute(SelectDescriptionLike,"%#{term}%").each do |row|
47
+ le = LogEntry.new
48
+ le.quick_assign!(row[0], row[1], Time.at(row[2]))
49
+ all.push le
50
+ end
51
+ all end
52
+
53
+ def insert
54
+ DbRegistry.instance.execute(InsertSql, @description, @date.to_i, @issue_id)
55
+ end
56
+
57
+ # Delete the loaded log entry currently in memory, by passing its id
58
+ def delete
59
+ self.delete(self.id)
60
+ end
61
+
62
+ def quick_assign!(id,desc,date,issue_id)
63
+ @id, @description, @date, @issue_id = id, desc, date, issue_id
64
+ end
65
+
66
+ # Print things nicely formmated no more than 80 cars (well, unless you stick
67
+ # the time in the end which is not counted for).
68
+ def to_s
69
+ str = "[#{id}] "
70
+ tmp = @description + " [#{@date.strftime("%H:%M:%S")}]"
71
+ desc = Helpers.break_string(tmp,80)
72
+ indent = " " * (id.to_s.split('').count + 5)
73
+ desc.gsub!(/#{$/}/, "#{$/}#{indent}")
74
+ str.concat(desc)
75
+ str end
76
+
77
+ # The identity field for the log entry DO
78
+ attr_accessor :id
79
+
80
+ # Text description for the log entry
81
+ attr_accessor :description
82
+
83
+ # Date the entry was created
84
+ attr_accessor :date
85
+
86
+ # The issue id (parent of this log entry)
87
+ attr_accessor :issue_id
88
+
89
+ private
90
+ def self.generic_find_all(sql, *params)
91
+ all = Array.new
92
+ DbRegistry.instance.execute(sql, *params).each do |row|
93
+ le = LogEntry.new
94
+ le.quick_assign!(row[0], row[1], Time.at(row[2]), row[3])
95
+ all.push le
96
+ end
97
+ all end
98
+ end
99
+ end # module Wlog
100
+
@@ -0,0 +1,21 @@
1
+ module Wlog
2
+ # The sql for attachments
3
+ # @author Simon Symeonidis
4
+ module AttachmentSql
5
+ # The table name
6
+ TableName = "attachments"
7
+
8
+ # Insert the file data into the database (NOTE wondering if small/big endian
9
+ # will be affecting this...)
10
+ InsertSql = "INSERT INTO #{TableName} (filename, given_name, data) "\
11
+ "values (?, ?, ?); "
12
+
13
+ # Delete by id
14
+ DeleteSql = "DELETE FROM #{TableName} WHERE discriminator = ? AND "\
15
+ "discriminator_id = ?;"
16
+
17
+ # Select an attachment given an id
18
+ SelectSql = "SELECT * FROM #{TableName} WHERE id = ? "
19
+ end
20
+ end
21
+
@@ -0,0 +1,28 @@
1
+ module Wlog
2
+ # Issue SQL
3
+ # @author Simon Symeonidis
4
+ module IssueSql
5
+ # The table name of the log entries table
6
+ TableName = "issues"
7
+
8
+ # Standard insert
9
+ InsertSql = \
10
+ "INSERT INTO #{TableName} "\
11
+ "(description, reported_date, due_date, status) "\
12
+ "values (?,?,?,?);"
13
+ # Standard delete
14
+ DeleteSql = "DELETE FROM #{TableName} WHERE id = ? ;"
15
+
16
+ # Standard update
17
+ UpdateSql = "UPDATE #{TableName} SET "\
18
+ "description = ? , reported_date = ? , due_date = ? , status = ?"\
19
+ "WHERE id = ?;"
20
+
21
+ # Select by id
22
+ SelectSql = "SELECT * FROM #{TableName} WHERE id = ? ;"
23
+
24
+ # Select all the issues
25
+ SelectAllSql = "SELECT * FROM #{TableName}; "
26
+ end
27
+ end
28
+
@@ -0,0 +1,20 @@
1
+ module Wlog
2
+ # Encapsulate the sql in only one part.
3
+ # @author Simon Symeonidis
4
+ module KeyValueSql
5
+ # The table name of the log entries table
6
+ TableName = "key_values"
7
+
8
+ # Standard insert
9
+ InsertSql = \
10
+ "INSERT INTO #{TableName} (key,value) values (?,?);"
11
+ # Standard delete
12
+ DeleteSql = "DELETE FROM #{TableName} WHERE key = ? ;"
13
+
14
+ # Standard update
15
+ UpdateSql = "UPDATE #{TableName} SET value = ? WHERE key = ?;"
16
+
17
+ # Select by key
18
+ Select = "SELECT * FROM #{TableName} WHERE key = ? ;"
19
+ end
20
+ end
@@ -0,0 +1,35 @@
1
+ module Wlog
2
+ # Encapsulate the sql in only one part.
3
+ # @author Simon Symeonidis
4
+ module LogEntrySql
5
+ # The table name of the log entries table
6
+ TableName = "log_entries"
7
+
8
+ # Standard insert
9
+ InsertSql = \
10
+ "INSERT INTO #{TableName} (description,date,issue_id) values (?,?,?);"
11
+ # Standard delete
12
+ DeleteSql = "DELETE FROM #{TableName} WHERE id = ? ;"
13
+
14
+ # Standard select all
15
+ SelectAll = "SELECT * FROM #{TableName} ORDER BY date ASC;"
16
+
17
+ # Standard update
18
+ UpdateSql = "UPDATE #{TableName} SET description = ? WHERE id = ?;"
19
+
20
+ # select all with a limit
21
+ SelectAllLimit = \
22
+ "SELECT * FROM #{TableName} WHERE date >="\
23
+ " #{Time.now.to_i - 604800 - 24 * 60 * 60} ORDER BY date ASC"
24
+
25
+ # Select by id
26
+ Select = "SELECT * FROM #{TableName} WHERE id = ? ;"
27
+
28
+ # Select by id
29
+ SelectAllByIssue = "SELECT * FROM #{TableName} WHERE issue_id = ? ;"
30
+
31
+ # Select by a regex like /.../i
32
+ SelectDescriptionLike = \
33
+ "SELECT * FROM #{TableName} WHERE description LIKE ?;"
34
+ end
35
+ end
@@ -0,0 +1,24 @@
1
+ module Wlog
2
+ # Sql for polymorphic attachments
3
+ # @author Simon Symeonidis
4
+ module PolymorphicAttachmentsSql
5
+
6
+ # The table name
7
+ TableName = "polymorphic_attachments"
8
+
9
+ # Select entries by discriminator name, and id
10
+ SelectSql = "SELECT * FROM #{TableName} WHERE "\
11
+ "discriminator = ? AND discriminator_id = ? "
12
+
13
+ # Insert an attachment given the current thing in hand
14
+ InsertSql = "INSERT INTO #{TableName} "\
15
+ "(discriminator, discriminator_id, attachment_id) values "\
16
+ "(? , ? , ?)"
17
+
18
+ # Delete an attachment from the attached thing
19
+ DeleteSql = "DELETE FROM #{TableName} WHERE "\
20
+ "discriminator = ? AND discriminator_id = ?"
21
+
22
+ end
23
+ end
24
+
@@ -0,0 +1,24 @@
1
+ module Wlog
2
+ # Static path data.
3
+ #
4
+ # Please follow the convention that if vars are dirs, then they end with '/'
5
+ #
6
+ # @author Simon Symeonidis
7
+ module StaticConfigurations
8
+ # The application name
9
+ AppName = "wlog"
10
+
11
+ # Absolute path to the configuration directory
12
+ ConfigDirectory = "#{ENV['HOME']}/.config/"
13
+
14
+ # Absolute path to the application directory
15
+ AppDirectory = "#{ConfigDirectory}#{AppName}/"
16
+
17
+ # Absolute path to the data directory
18
+ DataDirectory = "#{AppDirectory}data/"
19
+
20
+ # Default database name (when unspecified)
21
+ DefaultDb = "default"
22
+ end
23
+ end # module Wlog
24
+