wlog 1.1.1 → 1.1.5

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -48
  3. data/Rakefile +1 -0
  4. data/lib/wlog/commands/archive_finished_issues.rb +2 -2
  5. data/lib/wlog/commands/archive_issues.rb +1 -1
  6. data/lib/wlog/commands/bootstrap_templates.rb +37 -0
  7. data/lib/wlog/commands/concat_description.rb +7 -11
  8. data/lib/wlog/commands/delete_issue.rb +6 -5
  9. data/lib/wlog/commands/innit_db.rb +62 -6
  10. data/lib/wlog/commands/make_csv.rb +2 -6
  11. data/lib/wlog/commands/new_entry.rb +10 -7
  12. data/lib/wlog/commands/replace_pattern.rb +7 -5
  13. data/lib/wlog/domain/attachment.rb +50 -75
  14. data/lib/wlog/domain/invoice.rb +8 -2
  15. data/lib/wlog/domain/issue.rb +32 -132
  16. data/lib/wlog/domain/key_value.rb +10 -35
  17. data/lib/wlog/domain/log_entry.rb +18 -95
  18. data/lib/wlog/domain/static_configurations.rb +6 -0
  19. data/lib/wlog/domain/sys_config.rb +2 -5
  20. data/lib/wlog/migrations/make_standard_tables.rb +59 -0
  21. data/lib/wlog/ui/cli_interface.rb +55 -44
  22. data/lib/wlog/ui/commands/create_issue.rb +4 -8
  23. data/lib/wlog/ui/edit_handler.rb +74 -0
  24. data/lib/wlog/ui/invoice_ui.rb +133 -0
  25. data/lib/wlog/ui/issue_ui.rb +21 -77
  26. data/lib/wlog/ui/template_ui.rb +66 -0
  27. data/lib/wlog/version.rb +1 -1
  28. data/spec/domain/attachment_spec.rb +58 -59
  29. data/spec/domain/commands/concat_desc_spec.rb +10 -13
  30. data/spec/domain/commands/new_entry_spec.rb +10 -13
  31. data/spec/domain/commands/replace_pattern_spec.rb +11 -12
  32. data/spec/domain/issue_spec.rb +35 -38
  33. data/spec/domain/key_value_spec.rb +5 -8
  34. data/spec/domain/log_entry_spec.rb +20 -31
  35. data/spec/domain/sys_config_spec.rb +4 -7
  36. data/spec/make_db.rb +30 -4
  37. data/spec/tech/wlog_string_spec.rb +14 -14
  38. data/wlog.gemspec +2 -1
  39. metadata +26 -13
  40. data/lib/wlog/db_registry.rb +0 -38
  41. data/lib/wlog/domain/sql_modules/attachment_sql.rb +0 -21
  42. data/lib/wlog/domain/sql_modules/issue_sql.rb +0 -37
  43. data/lib/wlog/domain/sql_modules/key_value_sql.rb +0 -20
  44. data/lib/wlog/domain/sql_modules/log_entry_sql.rb +0 -35
  45. data/lib/wlog/ui/commands/attach_to_issue.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 881927105d2ad4db3a54716d36003cd94e2ce6fc
4
- data.tar.gz: 9b5f72a05d2924b8bfb3c0c669502abfc3bb0f98
3
+ metadata.gz: b2050581ce02c72f62ceee213cb8b10a7abaeafa
4
+ data.tar.gz: edb367143269344a076ac8470e55ff07c65dbb96
5
5
  SHA512:
6
- metadata.gz: 2c12ef90cef5b096c659415f4cb250a0953e3b345a94886fcf9a20db0b790a03ad745906bc796d61650005613e5e96592f187076a4b7c2a4136e8caf72601b6e
7
- data.tar.gz: 37da1bc3b3da242d01ddc7caaa506b8b782d0a950d4e086f397056c259327eb8bc29dc65f63b856889ee444540a78e9b71ff246106eb6726b56ad57c1265db38
6
+ metadata.gz: 3145857f03f3a6049bdc06ac393d44643973728e2da54f9a678acd9a04701f154ae6312f7b13e6605df169dca19762131b45abec00ff399abf9cf2f650f6f68d
7
+ data.tar.gz: c7f451d8b41d134adb47767229336848b93cd1922196298ce078c93949fdb14bbfb9d417d01f0aa466867d4b544b471cd931905f8f877cc2a5538c2061f745a8
data/README.md CHANGED
@@ -19,17 +19,13 @@ You can find the sources on github:
19
19
 
20
20
  ## Installation
21
21
 
22
- Add this line to your application's Gemfile:
22
+ Install it with:
23
23
 
24
- gem 'wlog'
25
-
26
- And then execute:
27
-
28
- $ bundle
24
+ $ gem install wlog
29
25
 
30
- Or install it yourself as:
26
+ Run with:
31
27
 
32
- $ gem install wlog
28
+ $ wlog
33
29
 
34
30
  ## Usage
35
31
 
@@ -47,32 +43,16 @@ The databases are located here:
47
43
 
48
44
  $HOME/.config/wlog/data/
49
45
 
50
- And you should be in a command line interface. In the interface you can type in
51
-
52
- help
53
-
54
- To see a list of actions that you can do.
55
-
56
- Usually you'll just need to write:
46
+ The next section will talk about this a little more.
57
47
 
58
- new
48
+ When you're in the command line interface, you can always run
59
49
 
60
- And enter the work description that you wish. You can add tags like this too
61
- in order to tag units of work:
62
-
63
- new
64
-
65
- Enter work description:
66
- I did something very productive today. #bugfix #completed #feature
50
+ help
67
51
 
68
- The tags can be pretty much anything you want, and for now are not very
69
- important. In the future however they might be used for something more useful.
52
+ in order to list the possible commands you can use.
70
53
 
71
54
  ### More Commands
72
55
 
73
- These are the commands that you can also use in order to exploit the full
74
- potential of this application.
75
-
76
56
  You can list the available databases by running the following command:
77
57
 
78
58
  wlog --list
@@ -94,7 +74,7 @@ So when you start the application this is what you see:
94
74
 
95
75
  Enter the command `show` to list the issues
96
76
 
97
- [wlog] show
77
+ [wlog] ls
98
78
  started work 2
99
79
  [6] Fix colors for wlog and make it pretty
100
80
  [4] Weird bug crash when pressing ctrl+d
@@ -103,14 +83,12 @@ Enter the command `show` to list the issues
103
83
 
104
84
  Now we want to focus on a particular issue. We type in `focus`
105
85
 
106
- [wlog] focus
107
- Focus on issue:
108
- 1
86
+ [wlog] focus 1
109
87
  [issue #1]
110
88
 
111
- And now we can show all the logged work with `show`:
89
+ And now we can show all the logged work with `ls` or `show`:
112
90
 
113
- [issue #1] show
91
+ [issue #1] ls
114
92
  2013-10-13 - Sunday [2]
115
93
  [4] I did some work on this issue [15:34:08]
116
94
  [5] Some trivial work there too [15:35:32]
@@ -121,20 +99,27 @@ To exit the scope of an issue, you can use the `forget` command:
121
99
  [issue #1] forget
122
100
  [wlog]
123
101
 
124
- If you forgot what you are doing, you can do
125
-
126
- [issue #1] desc
127
- + Issue #6
128
- - Reported : 2013-10-26 15:01:45 -0400
129
- - Due : 1969-12-31 19:00:00 -0500
130
- - Entries : 0
131
- - Status : started work
132
- - Time : 3h
133
-
134
- - Whatever description you wrote for issue 1
135
- - And here there exists an even larger description of the issue
136
-
137
- You can also attach files to issues
102
+ While in the scope of an issue, you can display its full description by invoking
103
+ the command `desc`.
104
+
105
+ [issue #4] desc
106
+
107
+ Issue #4
108
+ Reported : Sat Jul 12 00:46:27 2014
109
+ Due : Fri Oct 24 05:00:00 2014
110
+ Entries : 0
111
+ Status : started work
112
+ Time : 3w 4d 1h
113
+
114
+ Summary
115
+ This is some impressive work right here
116
+
117
+ Description
118
+ But this is an ever longer desc
119
+
120
+ You can also attach files to issues (you have to be outside the scope of an
121
+ issue for this - this feature is experimental at the momment so don't rely too
122
+ much on it):
138
123
 
139
124
  [wlog] attach
140
125
  Attach to which issue? : 1
data/Rakefile CHANGED
@@ -54,3 +54,4 @@ namespace :test do
54
54
  task :all => :spec
55
55
  end
56
56
 
57
+
@@ -7,8 +7,8 @@ module Wlog
7
7
  # @author Simon Symeonidis
8
8
  class ArchiveFinishedIssues < Commandable
9
9
 
10
- def initialize(db)
11
- @issues = Issue.find_all_finished(db)
10
+ def initialize
11
+ @issues = Issue.where(:status => 2)
12
12
  @arch_command = ArchiveIssues.new(@issues)
13
13
  end
14
14
 
@@ -14,7 +14,7 @@ class ArchiveIssues < Commandable
14
14
  def execute
15
15
  @issues.each do |issue|
16
16
  issue.archive!
17
- issue.update
17
+ issue.save
18
18
  end
19
19
  end
20
20
 
@@ -0,0 +1,37 @@
1
+ require 'wlog/commands/commandable'
2
+ require 'wlog/domain/static_configurations'
3
+
4
+ module Wlog
5
+ # To check if template dir exists or not. Make dirs. Add sample template.
6
+ # @author Simon Symeonidis
7
+ class BootstrapTemplates < Commandable
8
+ include StaticConfigurations
9
+
10
+ def initialize
11
+ end
12
+
13
+ def execute
14
+ unless File.exists? TemplateDir
15
+ FileUtils.mkdir_p TemplateDir
16
+ end
17
+
18
+ unless File.exists? TemplateSampleFile
19
+ write_default_template!
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ # Write a default template
26
+ def write_default_template!
27
+ fh = File.open(TemplateSampleFile, 'w')
28
+ data = "A list of issues:
29
+ <% @issues.each do |issue| %>
30
+ <%= \"\#{issue.id} \#{issue.description}\" %>
31
+ <% end %>"
32
+ fh.write(data)
33
+ fh.close
34
+ nil end
35
+
36
+ end
37
+ end
@@ -4,24 +4,20 @@ require 'wlog/domain/log_entry'
4
4
  module Wlog
5
5
  # Concatenate a string to an existing log entry
6
6
  class ConcatDescription < Commandable
7
- def initialize(db, id, str)
8
- @id = id; @str = str
9
- @db = db
7
+ def initialize(id, str)
8
+ @id, @str = id, str
10
9
  end
11
10
 
12
11
  # Find and update the log entry
13
12
  def execute
14
- log_entry = LogEntry.find(@db, @id)
15
- log_entry.description.concat(str)
16
- log_entry.update
13
+ log_entry = LogEntry.find(@id)
14
+ log_entry.description += @str
15
+ log_entry.save
16
+ rescue ActiveRecord::RecordNotFound
17
+ false
17
18
  end
18
19
 
19
20
  attr_reader :id, :str
20
-
21
- private
22
-
23
- attr :db
24
-
25
21
  end
26
22
  end # end Wlog module
27
23
 
@@ -5,20 +5,21 @@ module Wlog
5
5
  # Command for deleting issues
6
6
  # @author Simon Symeonidis
7
7
  class DeleteIssue
8
- # Init with the db handle, and issue id
9
- def initialize(db, id)
10
- @db = db
8
+ # Init with the issue id
9
+ def initialize(id)
11
10
  @issue_id = id
12
11
  @deleted = false
13
12
  end
14
13
 
15
14
  # delete the issue
16
15
  def execute
17
- issue = Issue.find(@db, @issue_id)
16
+ issue = Issue.find(@issue_id)
18
17
  if issue
19
- issue.delete
18
+ issue.destroy
20
19
  @deleted = true
21
20
  end
21
+ rescue ActiveRecord::RecordNotFound
22
+ @deleted = false
22
23
  end
23
24
 
24
25
  def deleted?
@@ -1,20 +1,76 @@
1
- require 'turntables/turntable'
2
-
3
- require 'wlog/db_registry'
4
1
  require 'wlog/commands/commandable'
5
2
  require 'wlog/domain/static_configurations'
6
3
 
4
+ require 'wlog/migrations/make_standard_tables'
5
+
6
+ require 'active_record'
7
+ require 'sqlite3'
8
+
7
9
  module Wlog
10
+
11
+ # Only used here
12
+ class MakeSchemaMigration < ActiveRecord::Migration
13
+ def change
14
+ create_table :schema_migrations do |t|
15
+ t.text :version
16
+ end
17
+ end
18
+ end
19
+
20
+ # Only used here
21
+ class SchemaMigration < ActiveRecord::Base
22
+ end
23
+
8
24
  # Command to create the initial database
9
25
  # @author Simon Symeonidis
10
26
  class InnitDb < Commandable
11
27
  include StaticConfigurations
12
28
  def execute
13
29
  current_dir = "#{File.expand_path File.dirname(__FILE__)}/../sql"
14
- turntable = Turntables::Turntable.new
15
- turntable.register(current_dir)
16
- turntable.make_at!("#{DataDirectory}#{ARGV[0] || DefaultDb}")
30
+ make_schema_migrations!
31
+ execute_migrations!
17
32
  end
33
+
34
+ # TODO making this public is hacky, but I'm doing this for now for being able
35
+ # to test. Once tests are ok again, then I'm going to refactor this somewhere
36
+ # else so it's more sane.
37
+ def execute_migrations!
38
+ migrations = [MakeStandardTables]
39
+ existing = SchemaMigration.all.collect{ |el| el.version }
40
+
41
+ migrations.reject!{ |e| existing.include? e.to_s}
42
+
43
+ migrations.each do |migration|
44
+ ActiveRecord::Migration.run(migration)
45
+ SchemaMigration.create(:version => migration.name)
46
+ end
47
+ end
48
+
49
+
50
+ private
51
+
52
+ # Checks to see if versioning table is there. Create if not.
53
+ def make_schema_migrations!
54
+ ActiveRecord::Base.configurations = dbconfig
55
+ ActiveRecord::Base.establish_connection(:development)
56
+ ActiveRecord::Base.default_timezone = :local
57
+
58
+ unless SchemaMigration.table_exists?
59
+ ActiveRecord::Migration.verbose = false
60
+ ActiveRecord::Migration.run(MakeSchemaMigration)
61
+ end
62
+ end
63
+
64
+ # TODO this should probably be moved
65
+ def dbconfig
66
+ dbname = ARGV[0] || DefaultDb
67
+ {'development' => {
68
+ :adapter => 'sqlite3',
69
+ :pool => 5,
70
+ :database => DataDirectory + dbname,
71
+ :timeout => 5000 }}
72
+ end
73
+
18
74
  end
19
75
  end
20
76
 
@@ -7,15 +7,11 @@ module Wlog
7
7
  # @author Simon Symeonidis
8
8
  class MakeCsv < Commandable
9
9
 
10
- def initialize(db)
11
- @db = db
12
- end
13
-
14
10
  # TODO refactor me. Because I feel like a horrible piece of code.
15
11
  def execute
16
12
  str = ""
17
- LogEntry.find_all(@db).group_by{|el| el.date.strftime("%Y-%m-%d")}.each_pair do |key,value|
18
- str.concat("#{value.first.date.strftime("%A")} #{key}\n")
13
+ LogEntry.all.group_by{|el| el.created_at.strftime("%Y-%m-%d")}.each_pair do |key,value|
14
+ str.concat("#{value.first.created_at.strftime("%A")} #{key}\n")
19
15
  value.each do |entry|
20
16
  str.concat(",\"#{Helpers.break_string(entry.description,80)}\"#{$/}")
21
17
  end
@@ -1,3 +1,5 @@
1
+ require 'active_record'
2
+ require 'date'
1
3
  require 'wlog/commands/commandable'
2
4
  require 'wlog/domain/log_entry'
3
5
 
@@ -6,16 +8,17 @@ module Wlog
6
8
  # @author Simon Symeonidis
7
9
  class NewEntry < Commandable
8
10
 
9
- def initialize(db, desc, issue_id)
10
- @desc, @iid = desc, issue_id
11
- @db = db
11
+ def initialize(desc, issue)
12
+ @desc, @issue = desc, issue
12
13
  end
13
14
 
14
15
  def execute
15
- log_entry = LogEntry.new(@db)
16
- log_entry.description = @desc
17
- log_entry.issue_id = @iid
18
- log_entry.insert
16
+ log_entry = LogEntry.new(
17
+ :description => @desc,
18
+ :created_at => DateTime.now,
19
+ :updated_at => DateTime.now)
20
+
21
+ @issue.log_entries << log_entry
19
22
  end
20
23
  end
21
24
  end
@@ -5,14 +5,16 @@ module Wlog
5
5
  # Command that replaces a string pattern found in an entry, with another string
6
6
  # @author Simon Symeonidis
7
7
  class ReplacePattern < Commandable
8
- def initialize(db, id, oldpat, newpat)
9
- @db, @id, @oldpat, @newpat = db, id, oldpat, newpat
8
+ def initialize(id, oldpat, newpat)
9
+ @id, @oldpat, @newpat = id, oldpat, newpat
10
10
  end
11
11
 
12
12
  def execute
13
- log_entry = LogEntry.find(@db, @id)
14
- log_entry.description.gsub!(@oldpat, @newpat)
15
- log_entry.update
13
+ log_entry = LogEntry.find(@id)
14
+ log_entry.description = log_entry.description.gsub(/#{@oldpat}/, @newpat)
15
+ log_entry.save
16
+ rescue ActiveRecord::RecordNotFound
17
+ false
16
18
  end
17
19
  end
18
20
  end
@@ -1,88 +1,63 @@
1
- require 'wlog/db_registry'
2
- require 'wlog/domain/sql_modules/attachment_sql'
3
- require 'wlog/domain/sql_modules/polymorphic_attachments_sql'
4
-
1
+ require 'active_record'
5
2
  module Wlog
6
3
  # Following the Active Record pattern
7
4
  # OO way of handling blobs of data, to be stored in memory or in db.
8
- class Attachment
9
- include AttachmentSql
10
- include PolymorphicAttachmentsSql
5
+ class Attachment < ActiveRecord::Base
11
6
 
12
7
  # Can only initialize with a caller name and id, since relations to
13
8
  # attachments are polymorphic.
14
- def initialize(dbhandle, caller_name, caller_id)
15
- @caller_name, @caller_id, @db = caller_name, caller_id, dbhandle
16
- end
9
+ # def initialize(dbhandle, caller_name, caller_id)
10
+ # @caller_name, @caller_id, @db = caller_name, caller_id, dbhandle
11
+ # end
17
12
 
18
13
  # Find an attachment given an id
19
14
  # @param id is the attachment id to find
20
- def self.find_all_by_discriminator(db, name, id)
21
- arr = Array.new
22
- rows = db.execute(
23
- PolymorphicAttachmentsSql::SelectSql, name, id)
24
-
25
- rows.each do |row|
26
- arr.push self.find(db, name, row[2])
27
- end
28
- arr end
29
-
30
- # Delete an attachment
31
- # @param id the attachment with the id to delete
32
- def delete_by_discriminator(name, id)
33
- @db.execute(DeleteSql, id)
34
- end
35
-
36
- # Find an attachment by an identifier and polymorphic name
37
- # @param id is the identifier of the attachment to find
38
- # @param name is the name of the polymorphic thing
39
- def self.find(db, name, id)
40
- row = db.execute(AttachmentSql::SelectSql, id).first
41
- att = nil
42
- if row && !row.empty?
43
- att = Attachment.new(db, name, id)
44
- att.quick_assign!(row)
45
- end
46
- att end
47
-
48
- # Insert an attachment. This also creates the relation in the polymorphic
49
- # table.
50
- def insert
51
- unless @id
52
- @db.execute(
53
- AttachmentSql::InsertSql, @filename, @given_name, @data)
54
- ret = @db.last_row_from(AttachmentSql::TableName)
55
- @id = ret.first[0].to_i
56
- @db.execute(
57
- PolymorphicAttachmentsSql::InsertSql, @caller_name, @caller_id, @id)
58
- end
59
- end
60
-
61
- # Assign a row of data to self
62
- def quick_assign!(row)
63
- @id, @filename, @given_name, @data = row[0], row[1], row[2], row[3]
64
- nil end
65
-
66
- # Identifier of the object
67
- attr_accessor :id
68
-
69
- # Container for the actual binary data of whatever you're attaching.
70
- attr_accessor :data
71
-
72
- # The original filename of the file
73
- attr_accessor :filename
74
-
75
- # optional given name for the attachment
76
- attr_accessor :given_name
77
-
78
- # The class name of the calling object
79
- attr_accessor :caller_name
80
-
81
- # The caller id of the calling object
82
- attr_accessor :caller_id
15
+ # def self.find_all_by_discriminator(db, name, id)
16
+ # arr = Array.new
17
+ # rows = db.execute(
18
+ # PolymorphicAttachmentsSql::SelectSql, name, id)
19
+
20
+ # rows.each do |row|
21
+ # arr.push self.find(db, name, row[2])
22
+ # end
23
+ # arr end
24
+
25
+ # # Delete an attachment
26
+ # # @param id the attachment with the id to delete
27
+ # def delete_by_discriminator(name, id)
28
+ # @db.execute(DeleteSql, id)
29
+ # end
30
+
31
+ # # Find an attachment by an identifier and polymorphic name
32
+ # # @param id is the identifier of the attachment to find
33
+ # # @param name is the name of the polymorphic thing
34
+ # def self.find(db, name, id)
35
+ # row = db.execute(AttachmentSql::SelectSql, id).first
36
+ # att = nil
37
+ # if row && !row.empty?
38
+ # att = Attachment.new(db, name, id)
39
+ # att.quick_assign!(row)
40
+ # end
41
+ # att end
42
+
43
+ # # Insert an attachment. This also creates the relation in the polymorphic
44
+ # # table.
45
+ # def insert
46
+ # unless @id
47
+ # @db.execute(
48
+ # AttachmentSql::InsertSql, @filename, @given_name, @data)
49
+ # ret = @db.last_row_from(AttachmentSql::TableName)
50
+ # @id = ret.first[0].to_i
51
+ # @db.execute(
52
+ # PolymorphicAttachmentsSql::InsertSql, @caller_name, @caller_id, @id)
53
+ # end
54
+ # end
55
+
56
+ # # Assign a row of data to self
57
+ # def quick_assign!(row)
58
+ # @id, @filename, @given_name, @data = row[0], row[1], row[2], row[3]
59
+ # nil end
83
60
 
84
- # The database handle for the active record
85
- attr_accessor :db
86
61
  end
87
62
  end # module Wlog
88
63
 
@@ -1,9 +1,15 @@
1
+ require 'active_record'
2
+ require 'wlog/domain/log_entry'
3
+
1
4
  module Wlog
2
5
  # The invoice domain object - use this to manipulate invoice recordings, or
3
6
  # this along with some renderer and templates in order to create said invoices.
4
7
  # @author Simon Symeonidis
5
- class Invoice
6
- def initialize
8
+ class Invoice < ActiveRecord::Base
9
+
10
+ def log_entries_within_dates
11
+ LogEntry.where(created_at: from..to)
7
12
  end
13
+
8
14
  end
9
15
  end