ptf 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +8 -0
- data/bin/console +14 -0
- data/bin/ptf +14 -0
- data/bin/setup +7 -0
- data/lib/ptf/client/group.rb +23 -0
- data/lib/ptf/client/summary.rb +23 -0
- data/lib/ptf/client/task.rb +37 -0
- data/lib/ptf/client.rb +39 -0
- data/lib/ptf/commands/group/add.rb +50 -0
- data/lib/ptf/commands/group.rb +9 -0
- data/lib/ptf/commands/init.rb +65 -0
- data/lib/ptf/commands/list.rb +91 -0
- data/lib/ptf/commands/task/create.rb +70 -0
- data/lib/ptf/commands/task/edit.rb +55 -0
- data/lib/ptf/commands/task.rb +67 -0
- data/lib/ptf/commands.rb +13 -0
- data/lib/ptf/config.rb +42 -0
- data/lib/ptf/data/data_file.rb +42 -0
- data/lib/ptf/data/group.rb +107 -0
- data/lib/ptf/data/metadata_file.rb +237 -0
- data/lib/ptf/data.rb +9 -0
- data/lib/ptf/utilities/date.rb +63 -0
- data/lib/ptf/utilities/file_system.rb +83 -0
- data/lib/ptf/utilities.rb +28 -0
- data/lib/ptf/version.rb +3 -0
- data/lib/ptf.rb +10 -0
- data/ptf.gemspec +35 -0
- metadata +139 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'ptf/commands/task/create'
|
2
|
+
require 'ptf/commands/task/edit'
|
3
|
+
|
4
|
+
module Ptf
|
5
|
+
module Commands
|
6
|
+
module Task
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def show(id)
|
10
|
+
if !Ptf::Utilities::FileSystem.id_exist?(id.to_i)
|
11
|
+
puts "Task #{id} does not exist."
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
metadata_file = Ptf::Utilities::FileSystem.find_file id.to_i
|
16
|
+
|
17
|
+
if metadata_file.nil?
|
18
|
+
puts "Task #{id} has been closed. Reopen it with ptf task reopen ###."
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
info = Ptf::Data::MetadataFile.new(metadata_file)
|
23
|
+
|
24
|
+
data_file = File.join(Ptf::Utilities::FileSystem.data_dir, info.hash)
|
25
|
+
puts `cat #{data_file}`
|
26
|
+
end
|
27
|
+
|
28
|
+
def close(id)
|
29
|
+
if !Ptf::Utilities::FileSystem.id_exist?(id.to_i)
|
30
|
+
puts "Task #{id} does not exist."
|
31
|
+
return
|
32
|
+
end
|
33
|
+
|
34
|
+
metadata_file = Ptf::Utilities::FileSystem.find_file id.to_i
|
35
|
+
|
36
|
+
if metadata_file.nil?
|
37
|
+
puts "Task #{id} has been closed. Reopen it with ptf task reopen ###."
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
info = Ptf::Data::MetadataFile.create_from_file(metadata_file)
|
42
|
+
|
43
|
+
info.complete_now
|
44
|
+
end
|
45
|
+
|
46
|
+
def reopen(id)
|
47
|
+
if !Ptf::Utilities::FileSystem.id_exist?(id.to_i)
|
48
|
+
puts "Task #{id} does not exist."
|
49
|
+
return
|
50
|
+
end
|
51
|
+
|
52
|
+
metadata_file = Ptf::Utilities::FileSystem.find_file id.to_i, false
|
53
|
+
|
54
|
+
if metadata_file.nil?
|
55
|
+
puts "Task #{id} is already open. Close it with ptf task close ###."
|
56
|
+
return
|
57
|
+
end
|
58
|
+
|
59
|
+
info = Ptf::Data::MetadataFile.create_from_file(metadata_file)
|
60
|
+
|
61
|
+
info.reopen
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/ptf/commands.rb
ADDED
data/lib/ptf/config.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Ptf
|
4
|
+
module Config
|
5
|
+
YAML_LOCATION = File.join(Dir.home, ".ptfconfig")
|
6
|
+
|
7
|
+
EDITABLE = {
|
8
|
+
:default_group => "unassigned:NONE",
|
9
|
+
:base_dir => File.join(Dir.home, ".ptf")
|
10
|
+
}
|
11
|
+
|
12
|
+
STATIC = {
|
13
|
+
:file_permission => 0700,
|
14
|
+
:id_counter_start => "1",
|
15
|
+
:task_metadata_dir => "info",
|
16
|
+
:task_data_dir => "data",
|
17
|
+
:in_progress_dir => "open",
|
18
|
+
:completed_dir => "closed",
|
19
|
+
:tmp_dir => "tmp",
|
20
|
+
:task_counter_file => "id_counter",
|
21
|
+
:group_list_file => "group_list"
|
22
|
+
}
|
23
|
+
|
24
|
+
def self.get_config
|
25
|
+
yaml_settings = {}
|
26
|
+
|
27
|
+
yaml_settings = YAML.load(File.read(YAML_LOCATION)) if File.exist?(YAML_LOCATION)
|
28
|
+
|
29
|
+
EDITABLE.merge(yaml_settings).merge(STATIC)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.write_config(config)
|
33
|
+
new_config = EDITABLE.merge config.select { |k| EDITABLE.keys.include? k }
|
34
|
+
|
35
|
+
yaml_file = File.new(YAML_LOCATION, "w")
|
36
|
+
yaml_file.puts new_config.to_yaml
|
37
|
+
yaml_file.close
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Ptf
|
2
|
+
module Data
|
3
|
+
class DataFile
|
4
|
+
|
5
|
+
DIR_PATH = Ptf::Utilities::FileSystem.data_dir
|
6
|
+
|
7
|
+
# Initialize a new DataFile.
|
8
|
+
#
|
9
|
+
# @param metadata_file [Ptf::Data::MetadataFile] the associated metadata file.
|
10
|
+
#
|
11
|
+
# @raise [ArgumntError] if a MetadataFile is not given.
|
12
|
+
def initialize(metadata_file)
|
13
|
+
raise ArgumentError, "Metadata file not given." unless metadata_file.is_a? Ptf::Data::MetadataFile
|
14
|
+
|
15
|
+
@metadata_file = metadata_file
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns the full path to the data file.
|
19
|
+
#
|
20
|
+
# @return [String] the full path to the data file.
|
21
|
+
def data_file_path
|
22
|
+
File.join(DIR_PATH, @metadata_file.hash)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the header string for the file.
|
26
|
+
#
|
27
|
+
# @return [String] the header string for the data file.
|
28
|
+
def header_string
|
29
|
+
"##{@metadata_file.group.abbreviation}--#{@metadata_file.id} #{@metadata_file.title}\n#Due: #{@metadata_file.due_date_str}\n#Estimate: #{@metadata_file.estimate}\n\n\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
# Write the header string to the data file. Overwrites any data file for the same task.
|
33
|
+
def write_to_file
|
34
|
+
File.open(data_file_path, "w") do |f|
|
35
|
+
f.write header_string
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Ptf
|
2
|
+
module Data
|
3
|
+
class Group
|
4
|
+
|
5
|
+
def initialize(name, abbrev)
|
6
|
+
@name = name
|
7
|
+
@abbreviation = abbrev
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
@name
|
12
|
+
end
|
13
|
+
|
14
|
+
def abbreviation
|
15
|
+
@abbreviation
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"#{name}:#{abbreviation}"
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def from_name(group_name)
|
24
|
+
group_file = Ptf::Utilities::FileSystem.group_list_file
|
25
|
+
File.open(group_file, "r") do |f|
|
26
|
+
f.each_line do |l|
|
27
|
+
name, abbrev = l.gsub(/\s+/, "").split(":")
|
28
|
+
|
29
|
+
if group_name == name
|
30
|
+
return Group.new(name, abbrev)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def from_abbrev(group_abbrev)
|
40
|
+
group_file = Ptf::Utilities::FileSystem.group_list_file
|
41
|
+
File.open(group_file, "r") do |f|
|
42
|
+
f.each_line do |l|
|
43
|
+
name, abbrev = l.gsub(/\s+/, "").split(":")
|
44
|
+
|
45
|
+
if group_abbrev == abbrev
|
46
|
+
return Group.new(name, abbrev)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_group(group)
|
56
|
+
if(group.length <= 4 && group == group.upcase)
|
57
|
+
from_abbrev(group)
|
58
|
+
else
|
59
|
+
from_name(group)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def group_exist?(g)
|
64
|
+
group_file = Ptf::Utilities::FileSystem.group_list_file
|
65
|
+
|
66
|
+
File.open(group_file, "r") do |f|
|
67
|
+
f.each_line do |l|
|
68
|
+
name, abbrev = l.gsub(/\s+/, "").split(":")
|
69
|
+
|
70
|
+
if name == g || abbrev == g
|
71
|
+
return true
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
false
|
78
|
+
end
|
79
|
+
|
80
|
+
def all_groups
|
81
|
+
group_arr = []
|
82
|
+
|
83
|
+
File.open(Ptf::Utilities::FileSystem.group_list_file, "r") do |f|
|
84
|
+
f.each_line do |l|
|
85
|
+
name, abbrev = l.gsub(/\s+/, "").split(":")
|
86
|
+
|
87
|
+
group_arr.push (Ptf::Data::Group.new(name, abbrev))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
group_arr
|
92
|
+
end
|
93
|
+
|
94
|
+
def default_group
|
95
|
+
config = Ptf::Config.get_config
|
96
|
+
default_group = config[:default_group]
|
97
|
+
|
98
|
+
name, abbrev = default_group.gsub(/\s+/, "").split(":")
|
99
|
+
Ptf::Data::Group.new(name, abbrev)
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
@@ -0,0 +1,237 @@
|
|
1
|
+
module Ptf
|
2
|
+
module Data
|
3
|
+
# Represents a single Metadata file.
|
4
|
+
#
|
5
|
+
# @author Austin Blatt
|
6
|
+
# @since 0.1.0
|
7
|
+
class MetadataFile
|
8
|
+
|
9
|
+
# Create a MetadataFile object from the given input.
|
10
|
+
#
|
11
|
+
# @param title [String] the task's title.
|
12
|
+
# @param group [Ptf::Data::Group] the Group the task is associated with.
|
13
|
+
# @param due_date [DateTime, nil] the due date given for the task.
|
14
|
+
# @param estimate [Numeric, nil] the estimated time to complete the task.
|
15
|
+
# @param id [Integer] the unique ID number for this task.
|
16
|
+
#
|
17
|
+
# @return [Ptf::Data::MetadataFile] the metadata file for the task.
|
18
|
+
def self.create_from_input(title, group, due_date, estimate, id)
|
19
|
+
data = {
|
20
|
+
:title => title,
|
21
|
+
:group => group,
|
22
|
+
:due_date => due_date,
|
23
|
+
:estimate => estimate,
|
24
|
+
:id => id,
|
25
|
+
:created_at => DateTime.now,
|
26
|
+
:completed_at => nil
|
27
|
+
}
|
28
|
+
|
29
|
+
# Get the filepath for the infofile
|
30
|
+
open_dir = Ptf::Utilities::FileSystem.metadata_open_dir
|
31
|
+
group_dir = File.join(open_dir, group.name)
|
32
|
+
filepath = File.join(group_dir, id.to_s)
|
33
|
+
|
34
|
+
self.new(filepath, data)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Create a MetadataFile object from the given filepath.
|
38
|
+
#
|
39
|
+
# @param filepath [String] the full file path to the metadata file.
|
40
|
+
#
|
41
|
+
# @raise [ArgumentError] if the given filepath does not exist.
|
42
|
+
# @raise [ArgumentError] if the given file is not a metadata file.
|
43
|
+
#
|
44
|
+
# @return [Ptf::Data::MetadataFile] the object representation of the metadata file.
|
45
|
+
def self.create_from_file(filepath)
|
46
|
+
raise ArgumentError, "File #{filepath} does not exist." unless Ptf::Utilities::FileSystem.file_exist?(filepath)
|
47
|
+
|
48
|
+
data = {}
|
49
|
+
# parse file
|
50
|
+
File.open(filepath, "r") do |f|
|
51
|
+
f.each_line do |l|
|
52
|
+
key, val = l.gsub(/\s+/, "").split(":")
|
53
|
+
|
54
|
+
if key.nil? || !(key.is_a? String)
|
55
|
+
raise ArgumentError, "Error parsing file."
|
56
|
+
end
|
57
|
+
|
58
|
+
# Convert values to appropriate types
|
59
|
+
case key
|
60
|
+
when "group"
|
61
|
+
val = Ptf::Data::Group.from_name(val)
|
62
|
+
when "due_date", "created_at", "completed_at"
|
63
|
+
val = (val.nil? ? val : Ptf::Utilities::Date.str_to_datetime(val))
|
64
|
+
when "id"
|
65
|
+
val = val.to_i
|
66
|
+
when "estimate"
|
67
|
+
val = (val.nil? ? nil : val.to_i)
|
68
|
+
end
|
69
|
+
|
70
|
+
data[key.to_sym] = val
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
return self.new(filepath, data)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Initialize a new metadata file.
|
78
|
+
#
|
79
|
+
# @param filepath [String] the full path to the file.
|
80
|
+
# @param data [Hash] the data in the file.
|
81
|
+
# @option data [String] :title the task's title.
|
82
|
+
# @option data [Ptf::Data::Group] :group the Group the task is associated with.
|
83
|
+
# @option data [DateTime, nil] :due_date the due date given for the task.
|
84
|
+
# @option data [Integer, nil] :estimate the estimated time to complete the task.
|
85
|
+
# @option data [Integer] :id the unique ID number for this task.
|
86
|
+
# @option data [DateTime] :created_at the time the task was created.
|
87
|
+
# @option data [DateTime, nil] :completed_at the time the task was completed (nil if it has not been completed).
|
88
|
+
# @option data [String] :hash the file hash (the filepath of the data file).
|
89
|
+
def initialize(filepath, data)
|
90
|
+
@filepath = filepath
|
91
|
+
@data = data
|
92
|
+
end
|
93
|
+
|
94
|
+
# Add content to the metadata file.
|
95
|
+
#
|
96
|
+
# @param key [Symbol] the key for the new content.
|
97
|
+
# @param val [Object] the value for the new content.
|
98
|
+
#
|
99
|
+
# @raise [ArgumentError] if the key is not a symbol.
|
100
|
+
def add_content(key, val)
|
101
|
+
raise ArgumentError, "The key #{key} is not a symbol." unless key.is_a? Symbol
|
102
|
+
|
103
|
+
@data[key] = val
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns the title of the task.
|
107
|
+
#
|
108
|
+
# @return [String] the title of the task.
|
109
|
+
def title
|
110
|
+
@data[:title]
|
111
|
+
end
|
112
|
+
|
113
|
+
# Returns the group the task is associated with.
|
114
|
+
#
|
115
|
+
# @return [Ptf::Data::Group] the group the task is associated with.
|
116
|
+
def group
|
117
|
+
@data[:group]
|
118
|
+
end
|
119
|
+
|
120
|
+
# Returns the due date of the task.
|
121
|
+
#
|
122
|
+
# @return [DateTime, nil] the due date of the task or nil if no due date exists.
|
123
|
+
def due_date
|
124
|
+
@data[:due_date]
|
125
|
+
end
|
126
|
+
|
127
|
+
# Returns the due date of the task as a String.
|
128
|
+
#
|
129
|
+
# @return [String] the due date of the task as a string.
|
130
|
+
def due_date_str
|
131
|
+
return "" if due_date.nil?
|
132
|
+
|
133
|
+
Ptf::Utilities::Date.datetime_to_str(due_date)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns the due date of the task for the ptf list command.
|
137
|
+
#
|
138
|
+
# @return [String] the due date in the form 'Mon Dec 19 - 11AM -' or 'Mon Dec 9 - 2PM -'.
|
139
|
+
def due_date_list_format
|
140
|
+
return "" if due_date.nil?
|
141
|
+
|
142
|
+
due_date.strftime("%a %b %_d - %l%p -")
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns the estimated time to complete the task.
|
146
|
+
#
|
147
|
+
# @return [Numeric] the estimated time to compelte the task.
|
148
|
+
def estimate
|
149
|
+
@data[:estimate]
|
150
|
+
end
|
151
|
+
|
152
|
+
# Returns the date and time that the task was created at.
|
153
|
+
#
|
154
|
+
# @return [DateTime] the date and time that the task was created at.
|
155
|
+
def created_at
|
156
|
+
@data[:created_at]
|
157
|
+
end
|
158
|
+
|
159
|
+
# Returns the date and time that the task was created at as a String.
|
160
|
+
#
|
161
|
+
# @return [String] the date and time represented as a string.
|
162
|
+
def created_at_str
|
163
|
+
Ptf::Utilities::Date.datetime_to_str(@data[:created_at])
|
164
|
+
end
|
165
|
+
|
166
|
+
# Return the id of the task.
|
167
|
+
#
|
168
|
+
# @return [Integer] the ID number of the task.
|
169
|
+
def id
|
170
|
+
@data[:id]
|
171
|
+
end
|
172
|
+
|
173
|
+
# Return the hash of the task.
|
174
|
+
#
|
175
|
+
# @return [String] the hash of the metadata file (the name of the data file).
|
176
|
+
def hash
|
177
|
+
@data[:hash]
|
178
|
+
end
|
179
|
+
|
180
|
+
# Completes the task.
|
181
|
+
#
|
182
|
+
# Fills in the completed_at field with the current DateTime.
|
183
|
+
# Removes the metadata file from the in progress directory and writes it to the completed directory.
|
184
|
+
def complete_now
|
185
|
+
@data[:completed_at] = DateTime.now
|
186
|
+
|
187
|
+
`rm #{@filepath}`
|
188
|
+
@filepath = File.join(File.join(Ptf::Utilities::FileSystem.metadata_closed_dir, group.name), id.to_s)
|
189
|
+
|
190
|
+
write_to_file
|
191
|
+
end
|
192
|
+
|
193
|
+
def reopen
|
194
|
+
`rm #{@filepath}`
|
195
|
+
@filepath = File.join(File.join(Ptf::Utilities::FileSystem.metadata_open_dir, group.name), id.to_s)
|
196
|
+
|
197
|
+
write_to_file
|
198
|
+
end
|
199
|
+
|
200
|
+
def key_val_to_str(key, val)
|
201
|
+
str_val = val
|
202
|
+
case key
|
203
|
+
when :group
|
204
|
+
str_val = val.name
|
205
|
+
when :due_date, :created_at, :completed_at
|
206
|
+
str_val = (val.nil? ? "" : Ptf::Utilities::Date.datetime_to_str(val))
|
207
|
+
end
|
208
|
+
|
209
|
+
"#{key}:#{str_val}"
|
210
|
+
end
|
211
|
+
|
212
|
+
# Returns the data in the file as a String.
|
213
|
+
#
|
214
|
+
# @return [String] the entire Metadata file as a String.
|
215
|
+
def file_string
|
216
|
+
return_str = ""
|
217
|
+
@data.each do |key, val|
|
218
|
+
return_str += "#{key_val_to_str(key, val)}\n"
|
219
|
+
end
|
220
|
+
|
221
|
+
return_str
|
222
|
+
end
|
223
|
+
|
224
|
+
# Writes the metadata file. Overwrites any previous metadata file for the same task.
|
225
|
+
def write_to_file
|
226
|
+
file = File.new(@filepath, "w")
|
227
|
+
|
228
|
+
@data.each do |key, val|
|
229
|
+
file.puts "#{key_val_to_str(key, val)}"
|
230
|
+
end
|
231
|
+
file.close
|
232
|
+
end
|
233
|
+
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
data/lib/ptf/data.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
module Ptf
|
2
|
+
module Utilities
|
3
|
+
module Date
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def datetime_to_str(datetime)
|
7
|
+
raise ArgumentError, "DateTime expected. Received #{datetime.class} instead." unless datetime.is_a? DateTime
|
8
|
+
|
9
|
+
datetime.strftime('%Y%m%d%H%M%S')
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_datetime_from_str(str)
|
13
|
+
|
14
|
+
begin
|
15
|
+
dt = str_to_datetime(str)
|
16
|
+
return dt
|
17
|
+
rescue
|
18
|
+
end
|
19
|
+
|
20
|
+
time_regex = /([0-2]?\d):([0-5]\d):?([0-5]\d)?/
|
21
|
+
# Check if given time 12:21(:21)
|
22
|
+
match = time_regex.match(str).to_a
|
23
|
+
|
24
|
+
if !match.nil? && (match.length == 3 || match.length == 4)
|
25
|
+
now = DateTime.now
|
26
|
+
return DateTime.new(now.year, now.month, now.day, match[1].to_i, match[2].to_i, 0, now.zone)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Check if given date 12/27(/[15|2015])
|
30
|
+
date_regex = /^([01]?\d)\/([0-3]?\d)\/?(\d\d\d\d|\d\d)?$/
|
31
|
+
match = date_regex.match(str)
|
32
|
+
|
33
|
+
if !match.nil? && (match.length == 3 || match.length == 4)
|
34
|
+
now = DateTime.now
|
35
|
+
|
36
|
+
if !match[3].nil? && match[3].length == 2
|
37
|
+
year = 2000 + match[3].to_i
|
38
|
+
elsif !match[3].nil?
|
39
|
+
year = match[3].to_i
|
40
|
+
end
|
41
|
+
|
42
|
+
return DateTime.new((match[3].nil? ? now.year : year), match[1].to_i, match[2].to_i, 12, 0, 0, now.zone)
|
43
|
+
end
|
44
|
+
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def str_to_datetime(str)
|
49
|
+
date_regex = /^(\d\d\d\d)([01]\d)([0-3]\d)([0-2]\d)([0-5]\d)([0-5]\d)?$/
|
50
|
+
|
51
|
+
regex_match = date_regex.match(str)
|
52
|
+
|
53
|
+
raise ArgumentError, "Improperly formatted datetime string, #{str}." unless regex_match.to_a.length == 7
|
54
|
+
|
55
|
+
_, year, month, day, hour, minute, second = regex_match.to_a
|
56
|
+
|
57
|
+
DateTime.new(year.to_i, month.to_i, day.to_i, hour.to_i, minute.to_i, second.to_i)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Ptf
|
2
|
+
module Utilities
|
3
|
+
module FileSystem
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def file_exist?(filepath)
|
7
|
+
File.file?(filepath)
|
8
|
+
end
|
9
|
+
|
10
|
+
def config
|
11
|
+
@config = Ptf::Config.get_config if @config.nil?
|
12
|
+
|
13
|
+
@config
|
14
|
+
end
|
15
|
+
|
16
|
+
def file_permission
|
17
|
+
@config[:file_permission]
|
18
|
+
end
|
19
|
+
|
20
|
+
def base_dir
|
21
|
+
config[:base_dir]
|
22
|
+
end
|
23
|
+
|
24
|
+
def id_counter_file
|
25
|
+
File.join(base_dir, config[:task_counter_file])
|
26
|
+
end
|
27
|
+
|
28
|
+
def id_counter_starting_content
|
29
|
+
config[:id_counter_start]
|
30
|
+
end
|
31
|
+
|
32
|
+
def group_list_file
|
33
|
+
File.join(base_dir, config[:group_list_file])
|
34
|
+
end
|
35
|
+
|
36
|
+
def metadata_dir
|
37
|
+
File.join(base_dir, config[:task_metadata_dir])
|
38
|
+
end
|
39
|
+
|
40
|
+
def metadata_open_dir
|
41
|
+
File.join(metadata_dir, config[:in_progress_dir])
|
42
|
+
end
|
43
|
+
|
44
|
+
def metadata_closed_dir
|
45
|
+
File.join(metadata_dir, config[:completed_dir])
|
46
|
+
end
|
47
|
+
|
48
|
+
def data_dir
|
49
|
+
File.join(base_dir, config[:task_data_dir])
|
50
|
+
end
|
51
|
+
|
52
|
+
def tmp_dir
|
53
|
+
File.join(base_dir, config[:tmp_dir])
|
54
|
+
end
|
55
|
+
|
56
|
+
def id_exist?(id)
|
57
|
+
next_id = File.read(id_counter_file).to_i
|
58
|
+
|
59
|
+
(id < next_id && id > 0)
|
60
|
+
end
|
61
|
+
|
62
|
+
def find_file(id, open = true)
|
63
|
+
raise ArgumentError, "No task with id #{id} exists." unless id_exist?(id)
|
64
|
+
|
65
|
+
search_dir = (open ? metadata_open_dir : metadata_closed_dir)
|
66
|
+
groups = Ptf::Data::Group.all_groups
|
67
|
+
|
68
|
+
groups.each do |g|
|
69
|
+
dir = File.join(search_dir, g.name)
|
70
|
+
possible_id_file = File.join(dir, id.to_s)
|
71
|
+
|
72
|
+
if file_exist?(possible_id_file)
|
73
|
+
return possible_id_file
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'ptf/utilities/date'
|
2
|
+
require 'ptf/utilities/file_system'
|
3
|
+
|
4
|
+
module Ptf
|
5
|
+
module Utilities
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def datetime_to_str(datetime)
|
9
|
+
raise ArgumentError, "DateTime expected. Received #{datetime.class} instead." unless datetime.is_a? DateTime
|
10
|
+
|
11
|
+
datetime.strftime('%Y%m%d%H%M%S')
|
12
|
+
end
|
13
|
+
|
14
|
+
def str_to_datetime(str)
|
15
|
+
date_regex = /^([0-9][0-9][0-9][0-9])([01][0-9])([0-3][0-9])?([0-2][0-9])([0-5][0-9])([0-5][0-9])$/
|
16
|
+
|
17
|
+
regex_match = date_regex.match(str)
|
18
|
+
|
19
|
+
raise ArgumentError, "Improperly formatted datetime string." unless regex_match.to_a.length == 7
|
20
|
+
|
21
|
+
_, year, month, day, hour, minute, second = regex_match.to_a
|
22
|
+
|
23
|
+
DateTime.new(year.to_i, month.to_i, day.to_i, hour.to_i, minute.to_i, second.to_i)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/ptf/version.rb
ADDED