wlog 0.0.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile +1 -0
- data/README.md +72 -3
- data/Rakefile +31 -0
- data/bin/wlog +12 -6
- data/lib/wlog.rb +0 -1
- data/lib/wlog/commands/commandable.rb +9 -0
- data/lib/wlog/commands/concat_description.rb +21 -0
- data/lib/wlog/commands/innit_db.rb +22 -0
- data/lib/wlog/commands/make_csv.rb +24 -0
- data/lib/wlog/commands/new_entry.rb +16 -0
- data/lib/wlog/commands/replace_pattern.rb +21 -0
- data/lib/wlog/db_registry.rb +19 -31
- data/lib/wlog/domain/ansi_colors.rb +15 -0
- data/lib/wlog/domain/attachment.rb +80 -0
- data/lib/wlog/domain/helpers.rb +42 -0
- data/lib/wlog/domain/issue.rb +100 -0
- data/lib/wlog/domain/key_value.rb +55 -0
- data/lib/wlog/domain/log_entry.rb +100 -0
- data/lib/wlog/domain/sql_modules/attachment_sql.rb +21 -0
- data/lib/wlog/domain/sql_modules/issue_sql.rb +28 -0
- data/lib/wlog/domain/sql_modules/key_value_sql.rb +20 -0
- data/lib/wlog/domain/sql_modules/log_entry_sql.rb +35 -0
- data/lib/wlog/domain/sql_modules/polymorphic_attachments_sql.rb +24 -0
- data/lib/wlog/domain/static_configurations.rb +24 -0
- data/lib/wlog/domain/sys_config.rb +23 -0
- data/lib/wlog/sql/mono/1.sql +50 -0
- data/lib/wlog/sql/seq/.gitkeep +0 -0
- data/lib/wlog/ui/cli_interface.rb +152 -0
- data/lib/wlog/ui/commands/attach_to_issue.rb +0 -0
- data/lib/wlog/ui/commands/attach_to_log_entry.rb +11 -0
- data/lib/wlog/ui/commands/create_issue.rb +18 -0
- data/lib/wlog/ui/commands/ui_command.rb +9 -0
- data/lib/wlog/ui/issue_ui.rb +126 -0
- data/lib/wlog/version.rb +1 -1
- data/spec/key_vale_spec.rb +9 -0
- data/wlog.gemspec +6 -2
- metadata +61 -8
- data/lib/wlog/cli_interface.rb +0 -149
- data/lib/wlog/helpers.rb +0 -28
- data/lib/wlog/log_entry.rb +0 -102
- data/lib/wlog/static_configurations.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f836fd871076bafbd84142635212cf9e375ab42
|
4
|
+
data.tar.gz: bafc3472bdff32399995f256d52b3ad7fe47ebe2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fe3b1b4222f094092869ece6b7b82b54a6e83ae1be3b1f74b560f70e0e7c08a0885d4de802b7dbe718c29659340a893ee38931e217ab56d986ef39859cd1802
|
7
|
+
data.tar.gz: e991c87b690f1e472c871c681bc66f0edc2122359dbe5cc9d4648fda6097e848c2f3d7069a2f6ee0f7892514dae0a7a078c1ad070bf624bc76d9fe023dd81403
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,21 @@
|
|
1
|
-
# wlog
|
1
|
+
# wlog ![Code Climate](https://codeclimate.com/github/psyomn/wlog.png)
|
2
2
|
|
3
3
|
wlog (worklog) is a small utility to track tasks in command line. I use this
|
4
4
|
for things I work on and need to submit a list of stuff done on a particular
|
5
5
|
day.
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
On the long term, I wish to provide some kind of ability to interface with
|
8
|
+
redmine, and synchronize tasks. This way we'd be able to have a git-like
|
9
|
+
utitlity for issue tracking - that is log your work on your computer, and push
|
10
|
+
it to the server whenever you're done (or want to update others on your
|
11
|
+
progress).
|
12
|
+
|
13
|
+
## Source Location
|
14
|
+
|
15
|
+
You can find the sources on github:
|
16
|
+
|
17
|
+
[http://github.com/psyomn/wlog](http://github.com/psyomn/wlog)
|
18
|
+
|
9
19
|
|
10
20
|
## Installation
|
11
21
|
|
@@ -58,6 +68,65 @@ in order to tag units of work:
|
|
58
68
|
The tags can be pretty much anything you want, and for now are not very
|
59
69
|
important. In the future however they might be used for something more useful.
|
60
70
|
|
71
|
+
### More Commands
|
72
|
+
|
73
|
+
These are the commands that you can also use in order to exploit the full
|
74
|
+
potential of this application.
|
75
|
+
|
76
|
+
You can list the available databases by running the following command:
|
77
|
+
|
78
|
+
wlog --list
|
79
|
+
|
80
|
+
If for some reason you need to check out where the application stores the
|
81
|
+
databases, you can do the following:
|
82
|
+
|
83
|
+
wlog --where
|
84
|
+
|
85
|
+
That will print the absolute path to that directory.
|
86
|
+
|
87
|
+
At the moment there are two main uis in this application. One of the UI is to
|
88
|
+
demonstrate the issues that are currently to be worked on. Then you choose an
|
89
|
+
issue, and log your work on that particular issue only.
|
90
|
+
|
91
|
+
So when you start the application this is what you see:
|
92
|
+
|
93
|
+
[wlog]
|
94
|
+
|
95
|
+
Enter the command `show` to list the issues
|
96
|
+
|
97
|
+
[wlog] show
|
98
|
+
1 [started work] - This issue is here to ...
|
99
|
+
2 [finished] - This issue is here to treat you better than the last one
|
100
|
+
3 [new] - this issue just does not belong
|
101
|
+
|
102
|
+
Now we want to focus on a particular issue. We type in `focus`
|
103
|
+
|
104
|
+
[wlog] focus
|
105
|
+
Focus on issue:
|
106
|
+
1
|
107
|
+
[issue #1]
|
108
|
+
|
109
|
+
And now we can show all the logged work with `show`:
|
110
|
+
|
111
|
+
[issue #1] show
|
112
|
+
2013-10-13 - Sunday [2]
|
113
|
+
[4] I did some work on this issue [15:34:08]
|
114
|
+
[5] Some trivial work there too [15:35:32]
|
115
|
+
[issue #1]
|
116
|
+
|
117
|
+
You can run these commands in this 'sub-shell':
|
118
|
+
are `show`, `search`, `replace`, `delete`, and `concat`.
|
119
|
+
|
120
|
+
`show` lists the latest work log entries.
|
121
|
+
|
122
|
+
`search` searches the database for a pattern that you specify.
|
123
|
+
|
124
|
+
`replace` searches and replaces a pattern that you specify.
|
125
|
+
|
126
|
+
`delete` removes an entry from the database.
|
127
|
+
|
128
|
+
`concat` appends a string to the specified log entry.
|
129
|
+
|
61
130
|
## Contributing
|
62
131
|
|
63
132
|
1. Fork it
|
data/Rakefile
CHANGED
@@ -1 +1,32 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require "./lib/wlog/domain/static_configurations"
|
4
|
+
require 'yard'
|
5
|
+
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
7
|
+
|
8
|
+
# note: rake yard
|
9
|
+
YARD::Rake::YardocTask.new do |t|
|
10
|
+
t.options = ['--title', 'Wlog: the friendly worktime logger!', '-o', 'doc/']
|
11
|
+
end
|
12
|
+
|
13
|
+
namespace :db do
|
14
|
+
# Remove data directory. This will remove all your data
|
15
|
+
task :rm do
|
16
|
+
include Wlog::StaticConfigurations
|
17
|
+
puts "Removing data directories from #{DataDirectory}"
|
18
|
+
print "You sure you want to remove it? [y/n] "
|
19
|
+
FileUtils.rm_rf AppDirectory if $stdin.gets.match(/^y/i)
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Run the sqlite3 console with the default database"
|
23
|
+
task :c do
|
24
|
+
include Wlog::StaticConfigurations
|
25
|
+
sh "sqlite3 #{DataDirectory}#{DefaultDb}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
namespace :test do
|
30
|
+
task :all => :spec
|
31
|
+
end
|
32
|
+
|
data/bin/wlog
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'wlog/
|
3
|
+
require 'wlog/version'
|
4
|
+
require 'wlog/domain/static_configurations'
|
5
|
+
require 'wlog/ui/cli_interface'
|
4
6
|
|
5
7
|
include Wlog
|
6
8
|
|
7
|
-
puts "Worktime logger"
|
8
|
-
|
9
9
|
if ARGV.size > 0
|
10
10
|
case ARGV[0]
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
when "--list"
|
12
|
+
CliInterface.list_databases
|
13
|
+
when '--where'
|
14
|
+
puts StaticConfigurations::DataDirectory
|
15
|
+
when /--/
|
16
|
+
puts "Unknown command."
|
17
|
+
else
|
18
|
+
CliInterface.new.run
|
14
19
|
end
|
15
20
|
else
|
16
21
|
CliInterface.new.run
|
17
22
|
end
|
23
|
+
|
data/lib/wlog.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'wlog/commands/commandable'
|
2
|
+
require 'wlog/domain/log_entry'
|
3
|
+
|
4
|
+
module Wlog
|
5
|
+
# Concatenate a string to an existing log entry
|
6
|
+
class ConcatDescription < Commandable
|
7
|
+
def initialize(id, str)
|
8
|
+
@id = id; @str = str
|
9
|
+
end
|
10
|
+
|
11
|
+
# Find and update the log entry
|
12
|
+
def execute
|
13
|
+
log_entry = LogEntry.find(@id)
|
14
|
+
log_entry.description.concat(str)
|
15
|
+
log_entry.update
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :id, :str
|
19
|
+
end
|
20
|
+
end # end Wlog module
|
21
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'turntables/turntable'
|
2
|
+
|
3
|
+
require 'wlog/db_registry'
|
4
|
+
require 'wlog/commands/commandable'
|
5
|
+
require 'wlog/domain/static_configurations'
|
6
|
+
require 'wlog/domain/helpers'
|
7
|
+
|
8
|
+
module Wlog
|
9
|
+
# Command to create the initial database
|
10
|
+
# @author Simon Symeonidis
|
11
|
+
class InnitDb < Commandable
|
12
|
+
include StaticConfigurations
|
13
|
+
def execute
|
14
|
+
Helpers.make_dirs!
|
15
|
+
current_dir = "#{File.expand_path File.dirname(__FILE__)}/../sql"
|
16
|
+
turntable = Turntables::Turntable.new
|
17
|
+
turntable.register(current_dir)
|
18
|
+
turntable.make_at!("#{DataDirectory}#{ARGV[0] || DefaultDb}")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'wlog/commands/commandable'
|
2
|
+
require 'wlog/domain/log_entry'
|
3
|
+
require 'wlog/domain/helpers'
|
4
|
+
|
5
|
+
module Wlog
|
6
|
+
# Create a Csv report with this command
|
7
|
+
# @author Simon Symeonidis
|
8
|
+
class MakeCsv < Commandable
|
9
|
+
def execute
|
10
|
+
str = ""
|
11
|
+
LogEntry.find_all.group_by{|el| el.date.strftime("%Y-%m-%d")}.each_pair do |key,value|
|
12
|
+
str.concat("#{value.first.date.strftime("%A")} #{key}\n")
|
13
|
+
value.each do |entry|
|
14
|
+
str.concat(",\"#{Helpers.break_string(entry.description,80)}\"#{$/}")
|
15
|
+
end
|
16
|
+
str.concat($/)
|
17
|
+
end
|
18
|
+
@ret = str
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :ret
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'wlog/commands/commandable'
|
2
|
+
require 'wlog/domain/log_entry'
|
3
|
+
|
4
|
+
module Wlog
|
5
|
+
class NewEntry < Commandable
|
6
|
+
|
7
|
+
def initialize(desc,issue_id); @desc, @iid = desc, issue_id end
|
8
|
+
|
9
|
+
def execute
|
10
|
+
log_entry = LogEntry.new
|
11
|
+
log_entry.description = @desc
|
12
|
+
log_entry.issue_id = @iid
|
13
|
+
log_entry.insert
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'wlog/commands/commandable'
|
2
|
+
require 'wlog/domain/log_entry'
|
3
|
+
|
4
|
+
module Wlog
|
5
|
+
# Command that replaces a string pattern found in an entry, with another string
|
6
|
+
# @author Simon Symeonidis
|
7
|
+
class ReplacePattern < Commandable
|
8
|
+
def initialize(id, oldpat, newpat)
|
9
|
+
@id, @oldpat, @newpat = id, oldpat, newpat
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute
|
13
|
+
log_entry = LogEntry.find(id)
|
14
|
+
log_entry.description.gsub!(old_pattern, new_pattern)
|
15
|
+
log_entry.update
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :id, :oldpat, :newpat
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
data/lib/wlog/db_registry.rb
CHANGED
@@ -2,51 +2,39 @@ require 'singleton'
|
|
2
2
|
require 'sqlite3'
|
3
3
|
require 'fileutils'
|
4
4
|
|
5
|
-
require 'wlog/static_configurations.rb'
|
5
|
+
require 'wlog/domain/static_configurations.rb'
|
6
6
|
|
7
7
|
module Wlog
|
8
|
-
#
|
8
|
+
# @author Simon Symeonidis
|
9
9
|
# The db registry, using sqlite3
|
10
10
|
class DbRegistry
|
11
11
|
include Singleton
|
12
|
+
include StaticConfigurations
|
12
13
|
|
13
14
|
def initialize
|
14
|
-
|
15
|
-
make_tables = !database_exists?
|
16
|
-
|
17
|
-
@db_handle = SQLite3::Database.new(
|
18
|
-
"#{StaticConfigurations::DATA_DIRECTORY}"\
|
19
|
-
"#{ARGV[0] || StaticConfigurations::DEFAULT_DATABASE}")
|
20
|
-
|
21
|
-
if make_tables
|
22
|
-
execute(@@log_entry_sql)
|
23
|
-
end
|
15
|
+
@handle = SQLite3::Database.new("#{DataDirectory}#{ARGV[0] || DefaultDb}")
|
24
16
|
end
|
25
17
|
|
18
|
+
# execute a sql with varargs parameters
|
19
|
+
# @param *sql, first the sql string, then the parameters if the statement is
|
20
|
+
# to be prepared.
|
21
|
+
# @example Simple Usage
|
22
|
+
# DbRegistry.execute("SELECT * FROM table WHERE id = ?", 1)
|
26
23
|
def execute(*sql)
|
27
|
-
@
|
24
|
+
@handle.execute(*sql)
|
28
25
|
end
|
29
26
|
|
30
|
-
# the
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
def make_dirs
|
36
|
-
# Does the data dir path not exist?
|
37
|
-
unless File.exists? StaticConfigurations::DATA_DIRECTORY
|
38
|
-
FileUtils.mkdir_p StaticConfigurations::DATA_DIRECTORY
|
39
|
-
end
|
27
|
+
# Get the last row, given a table name. The table needs to have an id
|
28
|
+
def last_row_from(tablename)
|
29
|
+
query = "SELECT * FROM #{tablename} WHERE id =(SELECT MAX(id) FROM"\
|
30
|
+
" #{tablename});"
|
31
|
+
@handle.execute(query)
|
40
32
|
end
|
41
33
|
|
42
|
-
|
43
|
-
|
44
|
-
"#{StaticConfigurations::DATA_DIRECTORY}#{ARGV[0]\
|
45
|
-
|| StaticConfigurations::DEFAULT_DATABASE}"
|
46
|
-
end
|
34
|
+
# the database handle
|
35
|
+
attr_accessor :handle
|
47
36
|
|
48
|
-
|
49
|
-
"CREATE TABLE log_entries (id INTEGER PRIMARY KEY AUTOINCREMENT,"\
|
50
|
-
"description TEXT, date DATETIME);"
|
37
|
+
private
|
51
38
|
end
|
52
39
|
end # module Wlog
|
40
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Wlog
|
2
|
+
# @author Simon Symeonidis
|
3
|
+
# Store some ansi color codes in a module
|
4
|
+
# TODO this is a placeholder, and might not be correct.
|
5
|
+
module AnsiColors
|
6
|
+
Red = 32
|
7
|
+
Blue = 33
|
8
|
+
Green = 34
|
9
|
+
Cyan = 35
|
10
|
+
Magenta = 36
|
11
|
+
White = 37
|
12
|
+
Black = 38
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'wlog/db_registry'
|
2
|
+
require 'wlog/domain/sql_modules/attachment_sql'
|
3
|
+
require 'wlog/domain/sql_modules/polymorphic_attachments_sql'
|
4
|
+
|
5
|
+
module Wlog
|
6
|
+
# Following the Active Record pattern
|
7
|
+
# OO way of handling blobs of data, to be stored in memory or in db.
|
8
|
+
class Attachment
|
9
|
+
include AttachmentSql
|
10
|
+
include PolymorphicAttachmentsSql
|
11
|
+
|
12
|
+
# Can only initialize with a caller name and id, since relations to
|
13
|
+
# attachments are polymorphic.
|
14
|
+
def initialize(caller_name, caller_id)
|
15
|
+
@caller_name, @caller_id = caller_name, caller_id
|
16
|
+
end
|
17
|
+
|
18
|
+
# Find an attachment given an id
|
19
|
+
# @param id is the attachment id to find
|
20
|
+
def self.find_all_by_discriminator(name, id)
|
21
|
+
arr = Array.new
|
22
|
+
rows = DbRegistry.instance.execute(
|
23
|
+
PolymorphicAttachmentsSql::SelectSql, name, id)
|
24
|
+
|
25
|
+
rows.each do |row|
|
26
|
+
arr.push self.find(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 self.delete_by_discriminator(name, id)
|
33
|
+
DbRegistry.instance.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(name, id)
|
40
|
+
row = DbRegistry.instance.execute(AttachmentSql::SelectSql, id).first
|
41
|
+
att = Attachment.new(name, id)
|
42
|
+
att.quick_assign!(row)
|
43
|
+
att end
|
44
|
+
|
45
|
+
# Insert an attachment. This also creates the relation in the polymorphic
|
46
|
+
# table.
|
47
|
+
def insert
|
48
|
+
DbRegistry.instance.execute(
|
49
|
+
AttachmentSql::InsertSql, @filename, @given_name, @data)
|
50
|
+
ret = DbRegistry.instance.last_row_from(AttachmentSql::TableName)
|
51
|
+
@id = ret.first[0].to_i
|
52
|
+
DbRegistry.instance.execute(
|
53
|
+
PolymorphicAttachmentsSql::InsertSql, @caller_name, @caller_id, @id)
|
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
|
60
|
+
|
61
|
+
# Identifier of the object
|
62
|
+
attr_accessor :id
|
63
|
+
|
64
|
+
# Container for the actual binary data of whatever you're attaching.
|
65
|
+
attr_accessor :data
|
66
|
+
|
67
|
+
# The original filename of the file
|
68
|
+
attr_accessor :filename
|
69
|
+
|
70
|
+
# optional given name for the attachment
|
71
|
+
attr_accessor :given_name
|
72
|
+
|
73
|
+
# The class name of the calling object
|
74
|
+
attr_accessor :caller_name
|
75
|
+
|
76
|
+
# The caller id of the calling object
|
77
|
+
attr_accessor :caller_id
|
78
|
+
end
|
79
|
+
end # module Wlog
|
80
|
+
|