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