safedb 0.3.1011 → 0.4.1002
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +56 -19
- data/README.md +15 -15
- data/Rakefile +7 -0
- data/bin/safe +2 -2
- data/lib/{interprete.rb → cli.rb} +168 -121
- data/lib/controller/admin/README.md +47 -0
- data/lib/controller/admin/access.rb +47 -0
- data/lib/controller/admin/checkin.rb +83 -0
- data/lib/controller/admin/checkout.rb +57 -0
- data/lib/controller/admin/diff.rb +75 -0
- data/lib/{usecase → controller/admin}/export.rb +15 -14
- data/lib/controller/admin/goto.rb +52 -0
- data/lib/controller/admin/import.rb +54 -0
- data/lib/controller/admin/init.rb +113 -0
- data/lib/controller/admin/login.rb +88 -0
- data/lib/{usecase → controller/admin}/logout.rb +0 -0
- data/lib/controller/admin/open.rb +39 -0
- data/lib/{usecase → controller/admin}/token.rb +2 -2
- data/lib/controller/admin/tree.md +54 -0
- data/lib/{usecase → controller/admin}/use.rb +0 -0
- data/lib/controller/admin/view.rb +61 -0
- data/lib/{usecase → controller/api}/docker/README.md +0 -0
- data/lib/{usecase → controller/api}/docker/docker.rb +1 -1
- data/lib/{usecase → controller/api}/jenkins/README.md +0 -0
- data/lib/{usecase → controller/api}/jenkins/jenkins.rb +1 -1
- data/lib/{usecase → controller/api}/terraform/README.md +1 -1
- data/lib/{usecase → controller/api}/terraform/terraform.rb +1 -1
- data/lib/{usecase → controller/api}/vpn/README.md +1 -1
- data/lib/{usecase → controller/api}/vpn/vpn.ini +0 -0
- data/lib/{usecase → controller/api}/vpn/vpn.rb +0 -0
- data/lib/{usecase → controller}/config/README.md +0 -0
- data/lib/{usecase → controller}/edit/README.md +0 -0
- data/lib/controller/edit/editverse.rb +48 -0
- data/lib/controller/edit/put.rb +35 -0
- data/lib/controller/edit/remove.rb +29 -0
- data/lib/{usecase/update/README.md → controller/edit/rename.md} +0 -0
- data/lib/{usecase → controller}/files/README.md +1 -1
- data/lib/controller/files/read.rb +36 -0
- data/lib/{usecase/files/eject.rb → controller/files/write.rb} +15 -20
- data/lib/{usecase → controller}/id.rb +0 -0
- data/lib/controller/query/print.rb +26 -0
- data/lib/controller/query/queryverse.rb +39 -0
- data/lib/controller/query/show.rb +50 -0
- data/lib/{session/require.gem.rb → controller/requirer.rb} +13 -9
- data/lib/{usecase → controller}/set.rb +4 -4
- data/lib/controller/usecase.rb +244 -0
- data/lib/{usecase → controller}/verse.rb +0 -0
- data/lib/{usecase → controller}/visit/README.md +0 -0
- data/lib/{usecase → controller}/visit/visit.rb +0 -0
- data/lib/factbase/facts.safedb.net.ini +7 -7
- data/lib/{keytools/key.docs.rb → model/README.md} +102 -66
- data/lib/model/book.rb +484 -0
- data/lib/model/branch.rb +48 -0
- data/lib/model/checkin.feature +33 -0
- data/lib/{configs/README.md → model/configs.md} +4 -4
- data/lib/model/content.rb +214 -0
- data/lib/model/indices.rb +132 -0
- data/lib/model/safe_tree.rb +51 -0
- data/lib/model/state.inspect.rb +221 -0
- data/lib/model/state.migrate.rb +334 -0
- data/lib/model/text_chunk.rb +68 -0
- data/lib/{extension → utils/extend}/array.rb +0 -0
- data/lib/{extension → utils/extend}/dir.rb +0 -0
- data/lib/{extension → utils/extend}/file.rb +0 -0
- data/lib/utils/extend/hash.rb +76 -0
- data/lib/{extension → utils/extend}/string.rb +6 -6
- data/lib/{session/fact.finder.rb → utils/facts/fact.rb} +0 -0
- data/lib/utils/identity/identifier.rb +356 -0
- data/lib/{keytools/key.ident.rb → utils/identity/machine.id.rb} +67 -4
- data/lib/utils/inspect/inspector.rb +81 -0
- data/lib/{keytools/kdf.bcrypt.rb → utils/kdfs/bcrypt.rb} +0 -0
- data/lib/{keytools → utils/kdfs}/kdf.api.rb +16 -16
- data/lib/{keytools/key.local.rb → utils/kdfs/kdfs.rb} +40 -40
- data/lib/{keytools/kdf.pbkdf2.rb → utils/kdfs/pbkdf2.rb} +0 -0
- data/lib/{keytools/kdf.scrypt.rb → utils/kdfs/scrypt.rb} +0 -0
- data/lib/{keytools → utils}/key.error.rb +2 -2
- data/lib/{keytools → utils}/key.pass.rb +2 -2
- data/lib/{keytools → utils/keys}/key.64.rb +0 -0
- data/lib/{keytools → utils/keys}/key.rb +6 -2
- data/lib/{keytools/key.iv.rb → utils/keys/random.iv.rb} +0 -0
- data/lib/{logging/gem.logging.rb → utils/logs/logger.rb} +6 -5
- data/lib/{keytools/key.pair.rb → utils/store/datamap.rb} +48 -30
- data/lib/{keytools/key.db.rb → utils/store/datastore.rb} +38 -104
- data/lib/utils/store/merge-boys-school.json +40 -0
- data/lib/utils/store/merge-girls-school.json +48 -0
- data/lib/utils/store/merge-merged-data.json +56 -0
- data/lib/utils/store/struct.rb +75 -0
- data/lib/utils/store/test-commands.sh +24 -0
- data/lib/{keytools/key.now.rb → utils/time/timestamp.rb} +32 -21
- data/lib/version.rb +1 -1
- metadata +86 -73
- data/lib/extension/hash.rb +0 -33
- data/lib/keytools/key.algo.rb +0 -109
- data/lib/keytools/key.api.rb +0 -1326
- data/lib/keytools/key.id.rb +0 -322
- data/lib/modules/cryptology/amalgam.rb +0 -70
- data/lib/modules/cryptology/engineer.rb +0 -99
- data/lib/modules/mappers/dictionary.rb +0 -288
- data/lib/session/time.stamp.rb +0 -340
- data/lib/session/user.home.rb +0 -49
- data/lib/usecase/cmd.rb +0 -471
- data/lib/usecase/edit/delete.rb +0 -46
- data/lib/usecase/files/file_me.rb +0 -78
- data/lib/usecase/files/read.rb +0 -169
- data/lib/usecase/files/write.rb +0 -89
- data/lib/usecase/goto.rb +0 -57
- data/lib/usecase/import.rb +0 -157
- data/lib/usecase/init.rb +0 -61
- data/lib/usecase/login.rb +0 -72
- data/lib/usecase/open.rb +0 -71
- data/lib/usecase/print.rb +0 -40
- data/lib/usecase/put.rb +0 -81
- data/lib/usecase/show.rb +0 -138
- data/lib/usecase/update/rename.rb +0 -180
- data/lib/usecase/view.rb +0 -71
@@ -1,288 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
# coding: utf-8
|
3
|
-
|
4
|
-
module SafeDb
|
5
|
-
|
6
|
-
require 'inifile'
|
7
|
-
|
8
|
-
# An OpenSession dictionary is a <b>2D (two dimensional) hash</b> data
|
9
|
-
# structure backed by an encrypted file.
|
10
|
-
#
|
11
|
-
# It supports operations to <b>read from</b> and <b>write to</b> a known
|
12
|
-
# filepath and given the correct symmetric encryption key it will
|
13
|
-
#
|
14
|
-
# - decrypt <b>after reading from</b> the file and
|
15
|
-
# - encrypt <b>before writing to</b> the file
|
16
|
-
#
|
17
|
-
# This dictionary extends {Hash} in order to deliver on its core key value
|
18
|
-
# storage and retrieve use cases. Extend this dictionary and provide
|
19
|
-
# context specific methods through constants to read and write context
|
20
|
-
# specific data.
|
21
|
-
#
|
22
|
-
# == The <em>Current</em> Dictionary Section
|
23
|
-
#
|
24
|
-
# This Dictionary is <b>two-dimensional</b> so all key-value pairs are stored
|
25
|
-
# under the auspices of a section.
|
26
|
-
#
|
27
|
-
# The Dictionary can track the <b>current section</b> for you and all data
|
28
|
-
# exchanges can occur in lieu of a single section if you so wish by using
|
29
|
-
# the provided {put} and {get} methods.
|
30
|
-
#
|
31
|
-
# To employ section management functionality you should pass in a current
|
32
|
-
# <b>section id</b> when creating the dictionary.
|
33
|
-
#
|
34
|
-
# @example
|
35
|
-
# To use the dictionary in the raw (unextended) format you create
|
36
|
-
# write and read it like this.
|
37
|
-
#
|
38
|
-
# ----------------------------------------------------------------------
|
39
|
-
#
|
40
|
-
# my_dictionary = Dictionary.create( "/path/to/backing/file" )
|
41
|
-
#
|
42
|
-
# my_dictionary["user23"] = {}
|
43
|
-
# my_dictionary["user23"]["Name"] = "Joe Bloggs"
|
44
|
-
# my_dictionary["user23"]["Email"] = "joebloggs@example.com"
|
45
|
-
# my_dictionary["user23"]["Phone"] = "+44 07342 800080"
|
46
|
-
#
|
47
|
-
# my_dictionary.write( "crypt-key-1234-wxyz" )
|
48
|
-
#
|
49
|
-
# ----------------------------------------------------------------------
|
50
|
-
#
|
51
|
-
# my_dictionary = Dictionary.create( "/path/to/backing/file", "crypt-key-1234-wxyz" )
|
52
|
-
# puts my_dictionary.has_key? "user23" # => true
|
53
|
-
# puts my_dictionary["user23"].length # => 3
|
54
|
-
# puts my_dictionary["user23"]["Email"] # => "joebloggs@example.com"
|
55
|
-
#
|
56
|
-
# ----------------------------------------------------------------------
|
57
|
-
class Dictionary < Hash
|
58
|
-
|
59
|
-
attr_accessor :backing_filepath, :section_id
|
60
|
-
|
61
|
-
|
62
|
-
# Create either a new empty dictionary or unmarshal (deserialize) the
|
63
|
-
# dictionary from an encrypted file depending on whether a file exists
|
64
|
-
# at the backing_file parameter location.
|
65
|
-
#
|
66
|
-
# If the backing file indeed exists, the crypt key will be employed to
|
67
|
-
# decode and then decrypt the contents before the unmarshal operation.
|
68
|
-
#
|
69
|
-
# The filepath is stored as an instance variable hence the {write}
|
70
|
-
# operation does not need to be told <b>where to?</b>
|
71
|
-
#
|
72
|
-
# @example
|
73
|
-
# # Create Dictionary the first time
|
74
|
-
# my_dictionary = Dictionary.create( "/path/to/backing/file" )
|
75
|
-
#
|
76
|
-
# # Create Dictionary from an Encrypted Backing File
|
77
|
-
# my_dictionary = Dictionary.create( "/path/to/backing/file", "crypt-key-1234-wxyz" )
|
78
|
-
#
|
79
|
-
# @param backing_file [String]
|
80
|
-
# the backing file is the filepath to this Dictionary's encrypted
|
81
|
-
# backing file when serialized. If no file exists at this path the
|
82
|
-
# operation will instantiate and return a new empty {Hash} object.
|
83
|
-
#
|
84
|
-
# @param crypt_key [String]
|
85
|
-
# if the backing file exists then this parameter must contain a
|
86
|
-
# robust symmetric decryption key. The symmetric key will be used
|
87
|
-
# for decryption after the base64 encoded file is read.
|
88
|
-
#
|
89
|
-
# Note that the decryption key is never part of the dictionary object.
|
90
|
-
# This class method knows it but the new Dictionary has no crypt key
|
91
|
-
# instance variable. Another crypt key must then be introduced when
|
92
|
-
# serializing (writing) the dictionary back into a file.
|
93
|
-
#
|
94
|
-
# @return [Dictionary]
|
95
|
-
# return a new Dictionary that knows where to go if it needs
|
96
|
-
# to read (deserialize) or write (serialize) itself.
|
97
|
-
#
|
98
|
-
# If no file exists at the path a new empty {Hash} object is
|
99
|
-
# returned.
|
100
|
-
#
|
101
|
-
# If a file exists, then the crypt_key parameter is expected
|
102
|
-
# to be the decryption and key and the dictionary will be based
|
103
|
-
# on the decrypted contents of the file.
|
104
|
-
#
|
105
|
-
# @raise [ArgumentError]
|
106
|
-
# An {ArgumentError} is raised if either no decryption key is provided
|
107
|
-
# or one that is unsuitable (ie was not used within the encryption).
|
108
|
-
# Errors can also arise if the block coding and decoding has not been
|
109
|
-
# done satisfactorily.
|
110
|
-
def self.create backing_file, crypt_key = nil
|
111
|
-
|
112
|
-
key_missing = File.file?( backing_file ) && crypt_key.nil?
|
113
|
-
raise ArgumentError, "No crypt key provided for file #{backing_file}" if key_missing
|
114
|
-
|
115
|
-
dictionary = Dictionary.new
|
116
|
-
dictionary.backing_filepath = backing_file
|
117
|
-
|
118
|
-
return dictionary unless File.file? backing_file
|
119
|
-
|
120
|
-
file_contents = File.read( backing_file ).strip
|
121
|
-
plaintext_str = file_contents.block_decode_decrypt( crypt_key )
|
122
|
-
dictionary.ingest_contents( plaintext_str )
|
123
|
-
|
124
|
-
return dictionary
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
|
129
|
-
# Create either a new dictionary containing the specified section or unmarshal
|
130
|
-
# (deserialize) the dictionary from an encrypted file depending on whether a
|
131
|
-
# file exists at the backing_file parameter location and then <b>create</b> the
|
132
|
-
# section <b>only if it does not exist</b>.
|
133
|
-
#
|
134
|
-
# If the backing file indeed exists, the crypt key will be employed to
|
135
|
-
# decode and then decrypt the contents before the unmarshal operation.
|
136
|
-
#
|
137
|
-
# The filepath is stored as an instance variable hence the {write}
|
138
|
-
# operation does not need to be told <b>where to?</b>
|
139
|
-
#
|
140
|
-
# This dictionary will also know which <b>"section"</b> should be used to
|
141
|
-
# put, add, update and delete key/value data. You can employ this dictionary
|
142
|
-
# such that <b>each instance only creates, updates, removes and/or reads</b>
|
143
|
-
# from a single section.
|
144
|
-
#
|
145
|
-
# @example
|
146
|
-
# # Create Dictionary the first time with a section.
|
147
|
-
# my_dictionary = Dictionary.create( "/path/to/file", "Europe" )
|
148
|
-
#
|
149
|
-
# # Create Dictionary from an Encrypted Backing File
|
150
|
-
# my_dictionary = Dictionary.create( "/path/to/file", "Europe", "1234-wxyz" )
|
151
|
-
#
|
152
|
-
# @param backing_file [String]
|
153
|
-
# the backing file is the filepath to this Dictionary's encrypted
|
154
|
-
# backing file when serialized.
|
155
|
-
#
|
156
|
-
# @param section_id [String]
|
157
|
-
# the created dictionary know which <b>section</b> should be used to
|
158
|
-
# put, add, update and delete key/value data. If the backing file
|
159
|
-
# does not exist a new section is created in the empty dictionary.
|
160
|
-
#
|
161
|
-
# If the file exists a new section is created only if it is not
|
162
|
-
# already present inside the dictionary.
|
163
|
-
#
|
164
|
-
# @param crypt_key [String]
|
165
|
-
# if the backing file exists then this parameter must contain a
|
166
|
-
# robust symmetric decryption key. The symmetric key will be used
|
167
|
-
# for decryption after the base64 encoded file is read.
|
168
|
-
#
|
169
|
-
# Note that the decryption key is never part of the dictionary object.
|
170
|
-
# This class method knows it but the new Dictionary has no crypt key
|
171
|
-
# instance variable. Another crypt key must then be introduced when
|
172
|
-
# serializing (writing) the dictionary back into a file.
|
173
|
-
#
|
174
|
-
# @return [Dictionary]
|
175
|
-
# return a new Dictionary that knows where to go if it needs
|
176
|
-
# to read (deserialize) or write (serialize) itself.
|
177
|
-
#
|
178
|
-
# If no file exists at the path a new empty {Hash} object is
|
179
|
-
# returned.
|
180
|
-
#
|
181
|
-
# If a file exists, then the crypt_key parameter is expected
|
182
|
-
# to be the decryption and key and the dictionary will be based
|
183
|
-
# on the decrypted contents of the file.
|
184
|
-
#
|
185
|
-
# @raise [ArgumentError]
|
186
|
-
# An {ArgumentError} is raised if either no decryption key is provided
|
187
|
-
# or one that is unsuitable (ie was not used within the encryption).
|
188
|
-
# Errors can also arise if the block coding and decoding has not been
|
189
|
-
# done satisfactorily.
|
190
|
-
def self.create_with_section backing_file, section_id, crypt_key = nil
|
191
|
-
|
192
|
-
dictionary = create( backing_file, crypt_key = nil )
|
193
|
-
dictionary.section_id = section_id
|
194
|
-
dictionary[section_id] = {} unless dictionary.has_key?( section_id )
|
195
|
-
|
196
|
-
return dictionary
|
197
|
-
|
198
|
-
end
|
199
|
-
|
200
|
-
|
201
|
-
# Write the data in this dictionary hash map into a file-system
|
202
|
-
# backend mirror whose path was specified in the {Dictionary.create}
|
203
|
-
# factory method.
|
204
|
-
#
|
205
|
-
# Technology for encryption at rest is mandatory when using this
|
206
|
-
# Dictionary to write and read files from the filesystem.
|
207
|
-
#
|
208
|
-
# Calling this {self.write} method when the file at the prescribed path
|
209
|
-
# does not exist results in the directory structure being created
|
210
|
-
# (if necessary) and then the (possibly encrypted) file being written.
|
211
|
-
#
|
212
|
-
# @param crypt_key [String]
|
213
|
-
# this parameter must contain a robust symmetric crypt key to use for
|
214
|
-
# the encryption before writing to the filesystem.
|
215
|
-
#
|
216
|
-
# Note that the decryption key is never part of the dictionary object.
|
217
|
-
# For uncrackable security this key must be changed every time the
|
218
|
-
# file is written.
|
219
|
-
def write crypt_key
|
220
|
-
|
221
|
-
ini_file = IniFile.new
|
222
|
-
self.each_key do |section_name|
|
223
|
-
ini_file[section_name] = self[section_name]
|
224
|
-
end
|
225
|
-
|
226
|
-
crypted_text = ini_file.to_s.encrypt_block_encode( crypt_key )
|
227
|
-
|
228
|
-
FileUtils.mkdir_p File.dirname(@backing_filepath)
|
229
|
-
File.write @backing_filepath, crypted_text
|
230
|
-
|
231
|
-
end
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
def get key_name
|
236
|
-
return self[@section_id][key_name]
|
237
|
-
end
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
def put key_name, key_value
|
242
|
-
self[@section_id][key_name] = key_value
|
243
|
-
end
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
# Ingest the contents of the INI string and merge it into a
|
249
|
-
# this object which is a {Hash}.
|
250
|
-
#
|
251
|
-
# @param the_contents [String]
|
252
|
-
# the INI string that will be ingested and morphed into
|
253
|
-
# this dictionary.
|
254
|
-
#
|
255
|
-
# @raise [ArgumentError]
|
256
|
-
# if the content contains any nil section name, key name
|
257
|
-
# or key value.
|
258
|
-
def ingest_contents the_contents
|
259
|
-
|
260
|
-
ini_file = IniFile.new( :content => the_contents )
|
261
|
-
ini_file.each do | data_group, data_key, data_value |
|
262
|
-
ingest_entry data_group, data_key, data_value
|
263
|
-
end
|
264
|
-
|
265
|
-
end
|
266
|
-
|
267
|
-
|
268
|
-
private
|
269
|
-
|
270
|
-
|
271
|
-
def ingest_entry section_name, key_name, value
|
272
|
-
|
273
|
-
msg = "A NIL object detected during ingestion of file [#{@filepath}]."
|
274
|
-
raise ArgumentError.new msg if section_name.nil? || key_name.nil? || value.nil?
|
275
|
-
|
276
|
-
if self.has_key? section_name then
|
277
|
-
self[section_name][key_name] = value
|
278
|
-
else
|
279
|
-
self.store section_name, { key_name => value }
|
280
|
-
end
|
281
|
-
|
282
|
-
end
|
283
|
-
|
284
|
-
|
285
|
-
end
|
286
|
-
|
287
|
-
|
288
|
-
end
|
data/lib/session/time.stamp.rb
DELETED
@@ -1,340 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
module OpenSession
|
4
|
-
|
5
|
-
require 'singleton'
|
6
|
-
|
7
|
-
# This stamp sits at the centre of a fundamental DevOps pattern concerned
|
8
|
-
# with infrastructure provisioning and configuraion management.
|
9
|
-
#
|
10
|
-
# The central idea behind the pattern is to link every infrastructure
|
11
|
-
# object created during a session with a reference accurate to the nearest
|
12
|
-
# centi-second denoting the moment the software runtime (session) began.
|
13
|
-
class Stamp
|
14
|
-
include Singleton
|
15
|
-
|
16
|
-
attr_reader :time_now
|
17
|
-
|
18
|
-
# Return two digit [mo] month index from 01 to 12.
|
19
|
-
# @example 02 => in February
|
20
|
-
def self.mo
|
21
|
-
return Stamp.instance.time_now.strftime "%m"
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
|
-
# Return three character abbreviated month name.
|
26
|
-
# @example feb => in February
|
27
|
-
def self.mmm
|
28
|
-
return Stamp.instance.time_now.strftime( "%b" ).downcase
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
# Return three character abbreviated day of week.
|
33
|
-
# @example tue => on Tuesday
|
34
|
-
def self.ddd
|
35
|
-
return Stamp.instance.time_now.strftime( "%a" ).downcase
|
36
|
-
end
|
37
|
-
|
38
|
-
|
39
|
-
# Return two digit (character) hour of day from 00 to 23.
|
40
|
-
# @example 22 => between 22.00.00 and 22.59.59 inclusive
|
41
|
-
def self.hh
|
42
|
-
return Stamp.instance.time_now.strftime "%H"
|
43
|
-
end
|
44
|
-
|
45
|
-
|
46
|
-
# Return two digit minute of hour from [00] to [59].
|
47
|
-
def self.mm
|
48
|
-
return Stamp.instance.time_now.strftime "%M"
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
|
-
# Return two digit second of minute from [00] to [59].
|
53
|
-
def self.ss
|
54
|
-
return Stamp.instance.time_now.strftime "%S"
|
55
|
-
end
|
56
|
-
|
57
|
-
|
58
|
-
# Return a [3 digit] second and tenth of second
|
59
|
-
# representation.
|
60
|
-
#
|
61
|
-
# The final digit is derived from the 1000 sliced
|
62
|
-
# millisecond of second running from 000 to 999.
|
63
|
-
#
|
64
|
-
# <tt>Truncation (Not Rounding)</tt>
|
65
|
-
#
|
66
|
-
# The [final] digit is acquired by TRUNCATING
|
67
|
-
# (chopping off) the last 2 of the 3 millisecond
|
68
|
-
# digits. No rounding is applied.
|
69
|
-
#
|
70
|
-
# The 3 returned digits comprise of the
|
71
|
-
#
|
72
|
-
# - second of minute => 2 digits | [00] to [59] (and)
|
73
|
-
# - tenth of second => 1 digit from [0] to [9]
|
74
|
-
#
|
75
|
-
# @example
|
76
|
-
#
|
77
|
-
# => The time at the 562nd millisecond of the 49th
|
78
|
-
# second of the minute.
|
79
|
-
#
|
80
|
-
# => 3 chars
|
81
|
-
# => 495
|
82
|
-
def self.sst
|
83
|
-
millisec_string = Stamp.instance.time_now.strftime "%L"
|
84
|
-
return "#{ss}#{millisec_string[0]}"
|
85
|
-
end
|
86
|
-
|
87
|
-
|
88
|
-
# Return the [two] digit year (eg 19 for 2019).
|
89
|
-
# that we are currently in.
|
90
|
-
def self.yy
|
91
|
-
return Stamp.instance.time_now.strftime("%Y")[2..-1]
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
# Return the [four] digit year (eg 2019)
|
96
|
-
# that we are currently in.
|
97
|
-
def self.yyyy
|
98
|
-
return Stamp.instance.time_now.strftime("%Y")
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
# Return 3 digit julian day of year [001] to [366].
|
103
|
-
def self.jjj
|
104
|
-
return Stamp.instance.time_now.strftime "%j"
|
105
|
-
end
|
106
|
-
|
107
|
-
|
108
|
-
# [yymo_mmm] returns an amalgam of
|
109
|
-
#
|
110
|
-
# => the two-digit year
|
111
|
-
# => the two-digit month index (starting at 01)
|
112
|
-
# => a period (separator)
|
113
|
-
# => the abbreviated month name
|
114
|
-
#
|
115
|
-
# @example
|
116
|
-
# => 1908.aug
|
117
|
-
# => for August 2019
|
118
|
-
#
|
119
|
-
def self.yymo_mmm
|
120
|
-
return "#{yy}#{mo}.#{mmm}"
|
121
|
-
end
|
122
|
-
|
123
|
-
|
124
|
-
# Given two integer parameters (month index and 4 digit year) representing
|
125
|
-
# the month in question this method returns the [PREVIOUS MONTHS] character
|
126
|
-
# amalgam in the format [yymo_mmm] where
|
127
|
-
#
|
128
|
-
# => yy | previous month's two-digit year
|
129
|
-
# => mo | previous month's two-digit month index
|
130
|
-
# => . | a period (separator)
|
131
|
-
# => mmm | previous month's abbreviated month name
|
132
|
-
#
|
133
|
-
# -------------------
|
134
|
-
# Example 1 (Simple)
|
135
|
-
# -------------------
|
136
|
-
#
|
137
|
-
# returns char => 1907.jul
|
138
|
-
# 4 parameters => 8, 2019
|
139
|
-
# representing => August, 2019
|
140
|
-
#
|
141
|
-
# ----------------------
|
142
|
-
# Example 2 (Last Year)
|
143
|
-
# ----------------------
|
144
|
-
#
|
145
|
-
# returns char => 1812.dec
|
146
|
-
# 4 parameters => 1, 2019
|
147
|
-
# representing => January, 2019
|
148
|
-
def self.previous_month_chars this_month_index, this_4digit_year
|
149
|
-
|
150
|
-
prev_month_index = this_month_index == 1 ? 12 : ( this_month_index - 1 )
|
151
|
-
prev_2dig_mn_pad = sprintf '%02d', prev_month_index
|
152
|
-
prev_4digit_year = this_month_index == 1 ? ( this_4digit_year - 1 ) : this_4digit_year
|
153
|
-
prev_twodigit_yr = "#{prev_4digit_year.to_s}"[2..-1]
|
154
|
-
prev_months_name = Date::ABBR_MONTHNAMES[prev_month_index].downcase
|
155
|
-
|
156
|
-
return "#{prev_twodigit_yr}#{prev_2dig_mn_pad}.#{prev_months_name}"
|
157
|
-
|
158
|
-
end
|
159
|
-
|
160
|
-
# Using the current class time this method returns
|
161
|
-
# the character amalgam for the [PREVIOUS MONTH] in
|
162
|
-
# the format [yymo_mmm] where
|
163
|
-
#
|
164
|
-
# => yy | last month's two-digit year
|
165
|
-
# => mo | last month's two-digit month index
|
166
|
-
# => . | a period (separator)
|
167
|
-
# => mmm | last month's abbreviated month name
|
168
|
-
#
|
169
|
-
# -------------------
|
170
|
-
# Example 1 (Simple)
|
171
|
-
# -------------------
|
172
|
-
#
|
173
|
-
# returns => 1907.jul
|
174
|
-
# if this month is => August 2019
|
175
|
-
#
|
176
|
-
# ----------------------
|
177
|
-
# Example 2 (Last Year)
|
178
|
-
# ----------------------
|
179
|
-
#
|
180
|
-
# returns => 1812.dec
|
181
|
-
# if this month is => January 2019
|
182
|
-
def self.yymo_mmm_prev
|
183
|
-
return previous_month_chars mo.to_i, yyyy.to_i
|
184
|
-
end
|
185
|
-
|
186
|
-
|
187
|
-
# Return 5 digit amalgam of year and julian day.
|
188
|
-
# eg [19003] for [January 3rd 2019]
|
189
|
-
def self.yyjjj
|
190
|
-
return "#{yy}#{jjj}"
|
191
|
-
end
|
192
|
-
|
193
|
-
|
194
|
-
# Return the 4 digit amalgam of the hour and minute
|
195
|
-
# using the 24 hour clock.
|
196
|
-
#
|
197
|
-
# @example
|
198
|
-
# => 1525
|
199
|
-
# => 03:25 pm
|
200
|
-
def self.hhmm
|
201
|
-
return "#{hh}#{mm}"
|
202
|
-
end
|
203
|
-
|
204
|
-
|
205
|
-
# Return the time of day to a TENTH of a second accuracy.
|
206
|
-
# [8] characters will always be returned with the 5th one
|
207
|
-
# being the (period) separator.
|
208
|
-
#
|
209
|
-
# The first (separated) segment delivers a hhmm 24 hour
|
210
|
-
# clock representation of the stamped time.
|
211
|
-
#
|
212
|
-
# The 3 digits of the second segment comprise of
|
213
|
-
#
|
214
|
-
# second of minute => 2 digits | [00] to [59]
|
215
|
-
# tenth of second => 1 digit from [0] to [9]
|
216
|
-
#
|
217
|
-
# @example
|
218
|
-
# => The time at the 562nd millisecond of the 49th
|
219
|
-
# second of the 23rd minute of the 17th hour of
|
220
|
-
# the day ( 17:23:49.562 )
|
221
|
-
#
|
222
|
-
# => 8 chars
|
223
|
-
# => 1723.495
|
224
|
-
def self.hhmm_sst
|
225
|
-
return "#{hhmm}.#{sst}"
|
226
|
-
end
|
227
|
-
|
228
|
-
|
229
|
-
# Return a string timestampt that is a period separated
|
230
|
-
# amalgam of the 2 digit year, 3 digit julian day, 2 digit
|
231
|
-
# hour, 2 digit minute, 2 digit second and 1 digit rounded
|
232
|
-
# down tenth of second.
|
233
|
-
#
|
234
|
-
# @example
|
235
|
-
# => 19003.1025
|
236
|
-
# => 10:25 am on January 3rd 2019
|
237
|
-
#
|
238
|
-
#
|
239
|
-
# Return the time of day to a TENTH of a second accuracy.
|
240
|
-
# [8] characters will always be returned with the 5th one
|
241
|
-
# being the (period) separator.
|
242
|
-
#
|
243
|
-
# The first (separated) segment delivers a hhmm 24 hour
|
244
|
-
# clock representation of the stamped time.
|
245
|
-
#
|
246
|
-
# The 3 digits of the second segment comprise of
|
247
|
-
#
|
248
|
-
# - second of minute => 2 digits | [00] to [59]
|
249
|
-
# - tenth of second => 1 digit from [0] to [9]
|
250
|
-
#
|
251
|
-
# @example
|
252
|
-
# => The time at the 562nd millisecond of the 49th
|
253
|
-
# second of the 23rd minute of the 17th hour of
|
254
|
-
# the day ( 17:23:49.562 )
|
255
|
-
#
|
256
|
-
# => 8 chars
|
257
|
-
# => 1723.495
|
258
|
-
def self.yyjjj_hhmm_sst
|
259
|
-
return "#{yyjjj}.#{hhmm}.#{sst}"
|
260
|
-
end
|
261
|
-
|
262
|
-
|
263
|
-
# Return a string timestampt that is a period separated
|
264
|
-
# amalgam of the 2 digit year, 3 digit julian day, 2 digit
|
265
|
-
# hour, 2 digit minute, 2 digit second and <b>9 digit</b>
|
266
|
-
# nanosecond.
|
267
|
-
#
|
268
|
-
# @example
|
269
|
-
# return => 19003.1725.42.836592034
|
270
|
-
# 4 time => 17:25:42 am on January 3rd 2019
|
271
|
-
#
|
272
|
-
# As per the above example, the time returned
|
273
|
-
#
|
274
|
-
# - is the 836592034 <b>nanosecond</b>
|
275
|
-
# - of the 42nd <b>second</b>
|
276
|
-
# - of the 25th <b>minute</b>
|
277
|
-
# - of the 17th <b>hour</b>
|
278
|
-
# - of the 3rd <b>day</b>
|
279
|
-
# - of the 20th <b>year</b>
|
280
|
-
# - of the 21st <b>century</b>
|
281
|
-
#
|
282
|
-
# @return [String]
|
283
|
-
# Return the time of day to nanosecond accuracy.
|
284
|
-
# 23 characters are always returned with three (3) period
|
285
|
-
# separators at the 6th, 11th and 14th positions.
|
286
|
-
def self.yyjjj_hhmm_ss_nanosec
|
287
|
-
nanosec_str = Stamp.instance.time_now.strftime "%9N"
|
288
|
-
return "#{yyjjj}.#{hhmm}.#{ss}.#{nanosec_str}"
|
289
|
-
end
|
290
|
-
|
291
|
-
|
292
|
-
# Return the Rubyfied time zone being used.
|
293
|
-
def self.zone
|
294
|
-
return Stamp.instance.time_now.zone
|
295
|
-
end
|
296
|
-
|
297
|
-
|
298
|
-
# Log segments of time pertaining to the time stamp.
|
299
|
-
# @todo
|
300
|
-
# move method contents into test class
|
301
|
-
def self.log_instance_time
|
302
|
-
|
303
|
-
log.info(x) { "[stamp] -------------- => -------------------------------- #" }
|
304
|
-
log.info(x) { "[stamp] eco time stamp => [#{Stamp.instance.time_now.ctime}]" }
|
305
|
-
log.info(x) { "[stamp] -------------- => -------------------------------- #" }
|
306
|
-
log.info(x) { "[stamp] Univ Time Zone => #{zone}" }
|
307
|
-
log.info(x) { "[stamp] Month Index is => #{mo}" }
|
308
|
-
log.info(x) { "[stamp] Month Name is => #{mmm}" }
|
309
|
-
log.info(x) { "[stamp] Day Of Week is => #{ddd}" }
|
310
|
-
log.info(x) { "[stamp] -------------- => -------------------------------- #" }
|
311
|
-
log.info(x) { "[stamp] Two Digit Year => #{yy}" }
|
312
|
-
log.info(x) { "[stamp] Julian Cal Day => #{jjj}" }
|
313
|
-
log.info(x) { "[stamp] Yr and Jul Day => #{yyjjj}" }
|
314
|
-
log.info(x) { "[stamp] Hour of Theday => #{hh}" }
|
315
|
-
log.info(x) { "[stamp] Minute of Hour => #{mm}" }
|
316
|
-
log.info(x) { "[stamp] Hour + Minute => #{hhmm}" }
|
317
|
-
log.info(x) { "[stamp] Second of Min => #{ss}" }
|
318
|
-
log.info(x) { "[stamp] 600 Min Slices => #{sst}" }
|
319
|
-
log.info(x) { "[stamp] -------------- => -------------------------------- #" }
|
320
|
-
log.info(x) { "[stamp] The Time Stamp => #{yyjjj_hhmm_sst}" }
|
321
|
-
log.info(x) { "[stamp] -------------- => -------------------------------- #" }
|
322
|
-
|
323
|
-
end
|
324
|
-
|
325
|
-
|
326
|
-
# This singleton (one instance) class sets the time just once.
|
327
|
-
def initialize
|
328
|
-
|
329
|
-
@time_now = Time.now;
|
330
|
-
|
331
|
-
end
|
332
|
-
|
333
|
-
|
334
|
-
############ Stamp.log_instance_time
|
335
|
-
|
336
|
-
|
337
|
-
end
|
338
|
-
|
339
|
-
|
340
|
-
end
|