safedb 0.3.1011 → 0.4.1002

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +56 -19
  3. data/README.md +15 -15
  4. data/Rakefile +7 -0
  5. data/bin/safe +2 -2
  6. data/lib/{interprete.rb → cli.rb} +168 -121
  7. data/lib/controller/admin/README.md +47 -0
  8. data/lib/controller/admin/access.rb +47 -0
  9. data/lib/controller/admin/checkin.rb +83 -0
  10. data/lib/controller/admin/checkout.rb +57 -0
  11. data/lib/controller/admin/diff.rb +75 -0
  12. data/lib/{usecase → controller/admin}/export.rb +15 -14
  13. data/lib/controller/admin/goto.rb +52 -0
  14. data/lib/controller/admin/import.rb +54 -0
  15. data/lib/controller/admin/init.rb +113 -0
  16. data/lib/controller/admin/login.rb +88 -0
  17. data/lib/{usecase → controller/admin}/logout.rb +0 -0
  18. data/lib/controller/admin/open.rb +39 -0
  19. data/lib/{usecase → controller/admin}/token.rb +2 -2
  20. data/lib/controller/admin/tree.md +54 -0
  21. data/lib/{usecase → controller/admin}/use.rb +0 -0
  22. data/lib/controller/admin/view.rb +61 -0
  23. data/lib/{usecase → controller/api}/docker/README.md +0 -0
  24. data/lib/{usecase → controller/api}/docker/docker.rb +1 -1
  25. data/lib/{usecase → controller/api}/jenkins/README.md +0 -0
  26. data/lib/{usecase → controller/api}/jenkins/jenkins.rb +1 -1
  27. data/lib/{usecase → controller/api}/terraform/README.md +1 -1
  28. data/lib/{usecase → controller/api}/terraform/terraform.rb +1 -1
  29. data/lib/{usecase → controller/api}/vpn/README.md +1 -1
  30. data/lib/{usecase → controller/api}/vpn/vpn.ini +0 -0
  31. data/lib/{usecase → controller/api}/vpn/vpn.rb +0 -0
  32. data/lib/{usecase → controller}/config/README.md +0 -0
  33. data/lib/{usecase → controller}/edit/README.md +0 -0
  34. data/lib/controller/edit/editverse.rb +48 -0
  35. data/lib/controller/edit/put.rb +35 -0
  36. data/lib/controller/edit/remove.rb +29 -0
  37. data/lib/{usecase/update/README.md → controller/edit/rename.md} +0 -0
  38. data/lib/{usecase → controller}/files/README.md +1 -1
  39. data/lib/controller/files/read.rb +36 -0
  40. data/lib/{usecase/files/eject.rb → controller/files/write.rb} +15 -20
  41. data/lib/{usecase → controller}/id.rb +0 -0
  42. data/lib/controller/query/print.rb +26 -0
  43. data/lib/controller/query/queryverse.rb +39 -0
  44. data/lib/controller/query/show.rb +50 -0
  45. data/lib/{session/require.gem.rb → controller/requirer.rb} +13 -9
  46. data/lib/{usecase → controller}/set.rb +4 -4
  47. data/lib/controller/usecase.rb +244 -0
  48. data/lib/{usecase → controller}/verse.rb +0 -0
  49. data/lib/{usecase → controller}/visit/README.md +0 -0
  50. data/lib/{usecase → controller}/visit/visit.rb +0 -0
  51. data/lib/factbase/facts.safedb.net.ini +7 -7
  52. data/lib/{keytools/key.docs.rb → model/README.md} +102 -66
  53. data/lib/model/book.rb +484 -0
  54. data/lib/model/branch.rb +48 -0
  55. data/lib/model/checkin.feature +33 -0
  56. data/lib/{configs/README.md → model/configs.md} +4 -4
  57. data/lib/model/content.rb +214 -0
  58. data/lib/model/indices.rb +132 -0
  59. data/lib/model/safe_tree.rb +51 -0
  60. data/lib/model/state.inspect.rb +221 -0
  61. data/lib/model/state.migrate.rb +334 -0
  62. data/lib/model/text_chunk.rb +68 -0
  63. data/lib/{extension → utils/extend}/array.rb +0 -0
  64. data/lib/{extension → utils/extend}/dir.rb +0 -0
  65. data/lib/{extension → utils/extend}/file.rb +0 -0
  66. data/lib/utils/extend/hash.rb +76 -0
  67. data/lib/{extension → utils/extend}/string.rb +6 -6
  68. data/lib/{session/fact.finder.rb → utils/facts/fact.rb} +0 -0
  69. data/lib/utils/identity/identifier.rb +356 -0
  70. data/lib/{keytools/key.ident.rb → utils/identity/machine.id.rb} +67 -4
  71. data/lib/utils/inspect/inspector.rb +81 -0
  72. data/lib/{keytools/kdf.bcrypt.rb → utils/kdfs/bcrypt.rb} +0 -0
  73. data/lib/{keytools → utils/kdfs}/kdf.api.rb +16 -16
  74. data/lib/{keytools/key.local.rb → utils/kdfs/kdfs.rb} +40 -40
  75. data/lib/{keytools/kdf.pbkdf2.rb → utils/kdfs/pbkdf2.rb} +0 -0
  76. data/lib/{keytools/kdf.scrypt.rb → utils/kdfs/scrypt.rb} +0 -0
  77. data/lib/{keytools → utils}/key.error.rb +2 -2
  78. data/lib/{keytools → utils}/key.pass.rb +2 -2
  79. data/lib/{keytools → utils/keys}/key.64.rb +0 -0
  80. data/lib/{keytools → utils/keys}/key.rb +6 -2
  81. data/lib/{keytools/key.iv.rb → utils/keys/random.iv.rb} +0 -0
  82. data/lib/{logging/gem.logging.rb → utils/logs/logger.rb} +6 -5
  83. data/lib/{keytools/key.pair.rb → utils/store/datamap.rb} +48 -30
  84. data/lib/{keytools/key.db.rb → utils/store/datastore.rb} +38 -104
  85. data/lib/utils/store/merge-boys-school.json +40 -0
  86. data/lib/utils/store/merge-girls-school.json +48 -0
  87. data/lib/utils/store/merge-merged-data.json +56 -0
  88. data/lib/utils/store/struct.rb +75 -0
  89. data/lib/utils/store/test-commands.sh +24 -0
  90. data/lib/{keytools/key.now.rb → utils/time/timestamp.rb} +32 -21
  91. data/lib/version.rb +1 -1
  92. metadata +86 -73
  93. data/lib/extension/hash.rb +0 -33
  94. data/lib/keytools/key.algo.rb +0 -109
  95. data/lib/keytools/key.api.rb +0 -1326
  96. data/lib/keytools/key.id.rb +0 -322
  97. data/lib/modules/cryptology/amalgam.rb +0 -70
  98. data/lib/modules/cryptology/engineer.rb +0 -99
  99. data/lib/modules/mappers/dictionary.rb +0 -288
  100. data/lib/session/time.stamp.rb +0 -340
  101. data/lib/session/user.home.rb +0 -49
  102. data/lib/usecase/cmd.rb +0 -471
  103. data/lib/usecase/edit/delete.rb +0 -46
  104. data/lib/usecase/files/file_me.rb +0 -78
  105. data/lib/usecase/files/read.rb +0 -169
  106. data/lib/usecase/files/write.rb +0 -89
  107. data/lib/usecase/goto.rb +0 -57
  108. data/lib/usecase/import.rb +0 -157
  109. data/lib/usecase/init.rb +0 -61
  110. data/lib/usecase/login.rb +0 -72
  111. data/lib/usecase/open.rb +0 -71
  112. data/lib/usecase/print.rb +0 -40
  113. data/lib/usecase/put.rb +0 -81
  114. data/lib/usecase/show.rb +0 -138
  115. data/lib/usecase/update/rename.rb +0 -180
  116. 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
@@ -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