wlog 1.1.1 → 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
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