ordinals 1.1.2 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19ed27e28ef41fc1d249f8275cc9a5dc829dee789693c3b32ee4af3ebfd40408
4
- data.tar.gz: 28b5186c473c0b21fcf493d446edb718c3715667cf1ba89eebff2609a7d0f28b
3
+ metadata.gz: 689dcb72a0c9c4a381e7389c99651c31373391ebc52ff342c2ab523778717fda
4
+ data.tar.gz: 1f444088a912221cedfcf2b1a13c8473ef666d68e2580f90c3e154ebe0334611
5
5
  SHA512:
6
- metadata.gz: 61a44488afd23242742de448620670b9b610ec68b5df9fe00c94f7e282449c41785476e35f4a78a29429a3d1ace452382eb62b42f4a013d69d84f88cd546b1da
7
- data.tar.gz: 9faa0175c1a53637db9f2119f9b20dd6c632c72f8f631b2daef505c67f85056820d1259bfe6f8d7c618dd8f26908f241f8dd467e7a7140db553137f53a63fb40
6
+ metadata.gz: 1624715a985b048b9223029e2fde16dbc8f3cb7fc3ffb401058dcfb20b8db072669b8a37784b62664f68e0adbe81711b375d3ebf8e28cd3bf4dc0ad53cda03f1
7
+ data.tar.gz: 7d29a44b6c4df9c76308fb4ce3daae7be30184e39d1ae18b714fc16143929d7ec3d5e16424040e3a0374460d78dee2d1987b5a8730158844df9d7878a870cbef
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 1.1.2
1
+ ### 1.2.1
2
2
 
3
3
  ### 0.0.1 / 2023-03-23
4
4
 
data/Manifest.txt CHANGED
@@ -4,8 +4,10 @@ README.md
4
4
  Rakefile
5
5
  lib/ordinals.rb
6
6
  lib/ordinals/api.rb
7
+ lib/ordinals/cache.rb
7
8
  lib/ordinals/recursive/composite.rb
8
9
  lib/ordinals/recursive/generator.rb
9
10
  lib/ordinals/recursive/image.rb
10
11
  lib/ordinals/sandbox.rb
11
12
  lib/ordinals/stats.rb
13
+ lib/ordinals/version.rb
data/README.md CHANGED
@@ -13,12 +13,15 @@ ordinals gem - ordinals (inscription) api wrapper & helpers for Bitcoin, Litcoin
13
13
 
14
14
 
15
15
  For now ordinal inscription api queries are supported on
16
- - Bitcoin (via <https://ordinals.com>)
17
- - Litecoin (via <https://ordinalslite.com>) and
18
- - Dogecoin (via <https://doginals.com>)
16
+ - Bitcoin (via <https://ordinals.com>) and
17
+ - Litecoin (via <https://ordinalslite.com>)
19
18
 
19
+ <!--
20
+ chekc if doginals still in operation???
21
+ - Dogecoin (via <https://doginals.com>)
22
+ -->
20
23
 
21
- Let's start querying for bitcoin (btc) ordinal inscriptions:
24
+ Let's start querying for bitcoin (btc) ordinal inscriptions by id:
22
25
 
23
26
  ``` ruby
24
27
  require 'ordinals'
@@ -44,20 +47,50 @@ pp data
44
47
  # "address"=>"bc1pyncs638hxfhaqjvnedw2lyc2jta6zuvr9erj6m9cwlghp6qqwvhqeq574l",
45
48
  # "output value"=>"9667",
46
49
  # "sat"=>"1391087135005306",
47
- # "preview"=>"link",
48
- # "content"=>"link",
49
- # "content length"=>"3072 bytes",
50
- # "content type"=>"image/png",
50
+ # "content-length"=>"3072 bytes",
51
+ # "content-type"=>"image/png",
51
52
  # "timestamp"=>"2023-02-18 03:02:18 UTC",
52
- # "genesis height"=>"777099",
53
- # "genesis fee"=>"1814",
54
- # "genesis transaction"=>"c41021cb11dce003e6a20a3420cf5954a1d104a1fe314393b915a62f020dcd0a",
53
+ # "genesis-height"=>"777099",
54
+ # "genesis-fee"=>"1814",
55
+ # "genesis-transaction"=>"c41021cb11dce003e6a20a3420cf5954a1d104a1fe314393b915a62f020dcd0a",
55
56
  # "location"=>"6a57dedb854c9bcac3fd2daab1172dd9a45f24c366dd8db33fe80557f11c6b39:22:0",
56
57
  # "output"=>"6a57dedb854c9bcac3fd2daab1172dd9a45f24c366dd8db33fe80557f11c6b39:22",
57
58
  # "offset"=>"0"}
58
59
  ```
59
60
 
60
61
 
62
+ Or by number (starting at 0):
63
+
64
+ ``` ruby
65
+ data = Ordinals.inscription( 21_000_000 )
66
+ pp data
67
+ # GET https://ordinals.com/inscription/4825a59486fa91ee88b6dd58caf0f9ba0f7273e2f30d9eccf9bfdabee55028d2i0...
68
+ #=> {"title"=>"Inscription 21000000",
69
+ # "id"=>"4825a59486fa91ee88b6dd58caf0f9ba0f7273e2f30d9eccf9bfdabee55028d2i0",
70
+ # "address"=>"bc1qq7dx8c9842jm6kf4gn83mft07jqtvye0gm5sq9",
71
+ # "output-value"=>"330",
72
+ # "sat"=>"1894095647358032",
73
+ # "content-length"=>"57 bytes",
74
+ # "content-type"=>"text/plain",
75
+ # "timestamp"=>"2023-08-02 11:00:22 UTC",
76
+ # "genesis-height"=>"801343",
77
+ # "genesis-fee"=>"842",
78
+ # "genesis-transaction"=>"4825a59486fa91ee88b6dd58caf0f9ba0f7273e2f30d9eccf9bfdabee55028d2",
79
+ # "location"=>"4825a59486fa91ee88b6dd58caf0f9ba0f7273e2f30d9eccf9bfdabee55028d2:0:0",
80
+ # "output"=>"4825a59486fa91ee88b6dd58caf0f9ba0f7273e2f30d9eccf9bfdabee55028d2:0",
81
+ # "offset"=>"0"}
82
+
83
+ content = Ordinals.content( 21_000_000 )
84
+ pp content
85
+ # GET https://ordinals.com/content/4825a59486fa91ee88b6dd58caf0f9ba0f7273e2f30d9eccf9bfdabee55028d2i0...
86
+ #=> <Ordinals::Api::Content:0x0000028bd4c1ff18
87
+ # @data="{\"p\":\"brc-20\",\"op\":\"mint\",\"tick\":\"sats\",\"amt\":\"99999999\"}",
88
+ # @length=nil,
89
+ # @type="text/plain">
90
+ ```
91
+
92
+
93
+
61
94
  Let's try querying for litecoin (ltc) ordinal inscriptions:
62
95
 
63
96
  ``` ruby
@@ -83,18 +116,43 @@ pp data
83
116
  #=> {"title"=>"Inscription 642",
84
117
  # "id"=>"f2b6adf7b2d0f128fb14817ff37f5f36e9176b17571e20c49871875553f937b4i0",
85
118
  # "address"=>"LSDz4fM4mLFyAZVoDuKyMHYq3af6cSZGSY",
86
- # "output value"=>"9878",
87
- # "preview"=>"link",
88
- # "content"=>"link",
89
- # "content length"=>"816 bytes",
90
- # "content type"=>"image/png",
119
+ # "output-value"=>"9878",
120
+ # "content-length"=>"816 bytes",
121
+ # "content-type"=>"image/png",
91
122
  # "timestamp"=>"2023-02-21 05:29:33 UTC",
92
- # "genesis height"=>"2426201",
93
- # "genesis fee"=>"361",
94
- # "genesis transaction"=>"f2b6adf7b2d0f128fb14817ff37f5f36e9176b17571e20c49871875553f937b4",
123
+ # "genesis-height"=>"2426201",
124
+ # "genesis-fee"=>"361",
125
+ # "genesis-transaction"=>"f2b6adf7b2d0f128fb14817ff37f5f36e9176b17571e20c49871875553f937b4",
95
126
  # "location"=>"6802c71b49f18aab91d0b363762b24afb1bf00c4820a5f782de6dd1b1cfbd68a:0:0",
96
127
  # "output"=>"6802c71b49f18aab91d0b363762b24afb1bf00c4820a5f782de6dd1b1cfbd68a:0",
97
128
  # "offset"=>"0"}
129
+
130
+
131
+ content = Ordinals.content( 0 )
132
+ pp content
133
+ # GET https://ordinalslite.com/content/71e0f6dc87a473aa69787fff8e09e5eddfdca96e587928a5b1a25c0ae16dc0eei0...
134
+ #=> <Ordinals::Api::Content:0x00000242a9a874e0
135
+ # @data="%PDF-1.3\...",
136
+ # @length=nil,
137
+ # @type="application/pdf">
138
+
139
+ data = Ordinals.inscription( 0 )
140
+ pp data
141
+ # GET https://ordinalslite.com/inscription/71e0f6dc87a473aa69787fff8e09e5eddfdca96e587928a5b1a25c0ae16dc0eei0...
142
+ #=> {"title"=>"Inscription 0",
143
+ # "id"=>"71e0f6dc87a473aa69787fff8e09e5eddfdca96e587928a5b1a25c0ae16dc0eei0",
144
+ # "address"=>"ltc1qz7qy4m8nhfqggxrtj308njs52lu9f5l9v7d5wd",
145
+ # "output-value"=>"10000",
146
+ # "sat"=>"906691404536244",
147
+ # "content-length"=>"57237 bytes",
148
+ # "content-type"=>"application/pdf",
149
+ # "timestamp"=>"2023-02-19 20:26:43 UTC",
150
+ # "genesis-height"=>"2425370",
151
+ # "genesis-fee"=>"15968",
152
+ # "genesis-transaction"=>"71e0f6dc87a473aa69787fff8e09e5eddfdca96e587928a5b1a25c0ae16dc0ee",
153
+ # "location"=>"71e0f6dc87a473aa69787fff8e09e5eddfdca96e587928a5b1a25c0ae16dc0ee:0:0",
154
+ # "output"=>"71e0f6dc87a473aa69787fff8e09e5eddfdca96e587928a5b1a25c0ae16dc0ee:0",
155
+ # "offset"=>"0"}
98
156
  ```
99
157
 
100
158
  That's it.
@@ -267,7 +325,7 @@ composite = RecursiveImageComposite.new( 10, 10, width: 96,
267
325
  data = read_json( "./ordinalpunks.json" )
268
326
  puts " #{data['items'].size} inscribe(s)"
269
327
 
270
- data['items'].each_with_index do |rec|
328
+ data['items'].each do |rec|
271
329
  id = rec['inscription_id']
272
330
  comment = rec['name']
273
331
 
@@ -353,7 +411,7 @@ Use it as you please with no restrictions whatsoever.
353
411
  ## Questions? Comments?
354
412
 
355
413
  Join us in the [Ordgen / ORC-721 discord (chat server)](https://discord.gg/dDhvHKjm2t). Yes you can.
356
- Your questions and commetary welcome.
414
+ Your questions and commentary welcome.
357
415
 
358
416
 
359
417
  Or post them over at the [Help & Support](https://github.com/geraldb/help) page. Thanks.
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'hoe'
2
+ require './lib/ordinals/version.rb'
2
3
 
3
4
 
4
5
  ###
@@ -10,7 +11,7 @@ require 'hoe'
10
11
 
11
12
  Hoe.spec 'ordinals' do
12
13
 
13
- self.version = '1.1.2'
14
+ self.version = Ordinals::VERSION
14
15
 
15
16
  self.summary = 'ordinals gem - ordinals (inscription) api wrapper & helpers for Bitcoin, Litecoin, Dogecoin & co.'
16
17
  self.description = summary
data/lib/ordinals/api.rb CHANGED
@@ -24,9 +24,13 @@ class Api ## change/rename Api to Client - why? why not?
24
24
  end
25
25
 
26
26
 
27
+ def config() Ordinals.config; end ## convenience shortcut helper
28
+
27
29
  def initialize( base, inscription: 'inscription' )
28
- @base = base
29
- @inscription = inscription
30
+ @base = base
31
+ @inscription = inscription
32
+ @requests = 0 ## count requests (for delay_in_s sleeping/throttling)
33
+ @pages = {} ## (0-)99, (100-)199, (200-)299 etc.
30
34
  end
31
35
 
32
36
 
@@ -46,8 +50,9 @@ class Content
46
50
  end ## (nested) class Content
47
51
 
48
52
 
53
+ def content( num_or_id )
54
+ id = num_or_id.is_a?( Integer ) ? _num_to_id( num_or_id ) : num_or_id
49
55
 
50
- def content( id )
51
56
  src = "#{@base}/content/#{id}"
52
57
  res = get( src )
53
58
 
@@ -67,6 +72,56 @@ end ## (nested) class Content
67
72
  end
68
73
 
69
74
 
75
+ INSCRIBE_ID_RX = %r{
76
+ inscription/(?<id>[a-fi0-9]+)
77
+ }ix
78
+
79
+
80
+ def inscription_ids( offset: ) ## note: page size is for now fixed 100
81
+ ids = []
82
+
83
+ src = "#{@base}/inscriptions/#{offset}"
84
+ res = get( src )
85
+
86
+ page = res.text ### assumes utf-8 for now
87
+ page.scan( INSCRIBE_ID_RX ) do |_|
88
+ m = Regexp.last_match
89
+ ids << m[:id]
90
+ end
91
+ puts " #{ids.size} inscribe id(s)"
92
+ ids = ids.reverse ## assume latest inscribe id is on top (reverse)
93
+ ids
94
+ end
95
+
96
+ def sub10k_ids
97
+ ids = []
98
+ limit = 100
99
+
100
+ 100.times do |i| ## fetch first hundred (100*100=10000) inscribe ids
101
+ offset = 99 + limit*i
102
+ puts "==> #{i} - @ #{offset}..."
103
+ ids += inscription_ids( offset: offset )
104
+ end
105
+ puts " #{ids.size} inscribe id(s) - total"
106
+ ids
107
+ end
108
+
109
+
110
+ def _num_to_id( num )
111
+ limit = 100
112
+ page, i = num.divmod( limit )
113
+ offset = 99+limit*page
114
+ ## e.g. 100.divmod( 100 ) => [1,0]
115
+ ## 100.divmod( 100 ) => [0,0]
116
+ ## 99.divmod( 100 ) => [0,99]
117
+ ## etc.
118
+
119
+ ## auto-add to page cache
120
+ ids = @pages[ offset ] ||= inscription_ids( offset: offset )
121
+ ids[i]
122
+ end
123
+
124
+
70
125
  =begin
71
126
  <dl>
72
127
  <dt>id</dt>
@@ -158,7 +213,9 @@ offset: 0
158
213
 
159
214
  =end
160
215
 
161
- def inscription( id )
216
+ def inscription( num_or_id )
217
+ id = num_or_id.is_a?( Integer ) ? _num_to_id( num_or_id ) : num_or_id
218
+
162
219
  src = "#{@base}/#{@inscription}/#{id}"
163
220
  res = get( src )
164
221
 
@@ -203,14 +260,34 @@ offset: 0
203
260
  data[ k ] = v
204
261
  end
205
262
  data
263
+
264
+
265
+ ## post process to convert to headers format
266
+ ## e.g. replace space with -
267
+ ## and remove/exclude content & preview
268
+ h = {}
269
+ data.each do |k,v|
270
+ next if ['preview', 'content'].include?( k )
271
+ h[ k.gsub( ' ', '-') ] = v
272
+ end
273
+ h
206
274
  end
207
275
 
208
276
 
209
277
  def get( src )
278
+ @requests += 1
279
+
280
+ if @requests > 1 && config.delay_in_s
281
+ puts "request no. #{@requests}@#{@base}; sleeping #{config.delay_in_s} sec(s)..."
282
+ sleep( config.delay_in_s )
283
+ end
284
+
210
285
  res = Webclient.get( src )
286
+
211
287
  if res.status.ok?
212
288
  res
213
289
  else
290
+ ## todo/fix: raise exception here!!!!
214
291
  puts "!! ERROR - HTTP #{res.status.code} #{res.status.message} - failed web request >#{src}<; sorry"
215
292
  exit 1
216
293
  end
@@ -0,0 +1,203 @@
1
+
2
+ module Ordinals
3
+
4
+ class Cache
5
+
6
+ def initialize( dir )
7
+ @dir = dir
8
+ @force = false
9
+ end
10
+
11
+
12
+
13
+ def json_to_txt( data )
14
+ buf = ''
15
+ data.each do |k,v|
16
+ next if ['preview', 'content'].include?( k )
17
+ buf << "#{k.gsub( ' ', '-')}: #{v}\n"
18
+ end
19
+ buf
20
+ end
21
+
22
+
23
+
24
+ def _find_blobs
25
+ ## note: *.{txt,json,png} will also include *.meta.txt
26
+ ### CANNOT use, thus, try *i?.*
27
+ Dir.glob( "#{@dir}/**/*i?.{txt,json,png}" )
28
+ end
29
+
30
+ def _find_meta
31
+ Dir.glob( "#{@dir}/**/*.meta.txt" )
32
+ end
33
+
34
+ def stats
35
+ paths = _find_meta
36
+ puts " #{paths.size} inscribe metadatafile(s) found"
37
+
38
+ paths = _find_blobs
39
+ puts " #{paths.size} inscribe blob(s) found"
40
+ end
41
+
42
+
43
+
44
+
45
+
46
+
47
+ def add( id )
48
+ ## step 1) get metadata records
49
+ meta_path = "#{@dir}/#{id[0,2]}/#{id[2..-1]}.meta.txt"
50
+
51
+ meta = nil
52
+ if !@force && File.exist?( meta_path )
53
+ meta = read_headers( meta_path )
54
+ print "."
55
+ else
56
+ print " meta-#{id} "
57
+
58
+ ## fetch and cache in cache
59
+ meta = Ordinals.inscription( id )
60
+ pp meta
61
+ meta_txt = json_to_txt( meta )
62
+
63
+ write_text( meta_path, meta_txt )
64
+ end
65
+
66
+
67
+ content_type = meta['content-type']
68
+ extname = if content_type.start_with?( 'text/plain' )
69
+ '.txt'
70
+ elsif content_type.start_with?( 'application/json' )
71
+ '.json'
72
+ elsif content_type.start_with?( 'image/png' )
73
+ '.png'
74
+ else
75
+ puts "!! ERROR - unexpected content type; got: #{content_type}"
76
+ ## pp meta
77
+ exit 1
78
+ end
79
+
80
+
81
+ path = "#{@dir}/#{id[0,2]}/#{id[2..-1]}#{extname}"
82
+ if !@force && File.exist?( path )
83
+ ## puts " in cache"
84
+ print "."
85
+ else
86
+ print " blob-#{id} "
87
+
88
+ ## note: save text as blob - byte-by-byte as is (might be corrupt text)
89
+ content = Ordinals.content( id )
90
+ ## pp content
91
+ ## puts "data:"
92
+ ## puts content.data
93
+
94
+ write_blob( path, content.data )
95
+ end
96
+ end # method add
97
+
98
+
99
+ def _prepare_csv( path )
100
+ ids = []
101
+ recs = read_csv( path )
102
+ recs.each do |rec|
103
+ ids << rec['id']
104
+ end
105
+ ids
106
+ end
107
+
108
+ def add_csv( path )
109
+ ids = _prepare_csv( path )
110
+ ids = ids.uniq ## make uniq by default - why? why not?
111
+ puts " #{ids.size} inscribe id(s)"
112
+ ids.each { |id| add(id) }
113
+ end
114
+
115
+
116
+
117
+ ## get inscription links
118
+ ## e.g.
119
+ ## inscription/e8830c5fbdfc2f529350fd04a2ac20bb097dce98f159223837513ae3c8d05714i0
120
+
121
+ =begin
122
+ INSCRIBE_ID_RX = %r{
123
+ /b # boundry (non-alphanum)
124
+ (?<id>[a-f0-9]{64}i[0-9])
125
+ /b # boundry (non-alphanum)
126
+ }ix
127
+ =end
128
+
129
+ INSCRIBE_ID_RX = %r{
130
+ inscription/(?<id>[a-fi0-9]+)
131
+ }ix
132
+
133
+
134
+ ##
135
+ ## strict rx gets:
136
+ ## 168 inscribe id(s)
137
+ ## 118 inscribe id(s) - unique
138
+ ##
139
+ ## loose gets:
140
+ ## 300 inscribe id(s)
141
+ ## 250 inscribe id(s) - unique
142
+ ##
143
+ ## /b for boundray NOT working - why? why not?
144
+
145
+
146
+ def _prepare_html( path )
147
+ ids = []
148
+ txt = read_text( path )
149
+ txt.scan( INSCRIBE_ID_RX ) do |_|
150
+ m = Regexp.last_match
151
+
152
+ ids << m[:id]
153
+ end
154
+ ids
155
+ end
156
+
157
+ def add_html( path )
158
+ ids = _prepare_html( path )
159
+ ids = ids.uniq ## make uniq by default - why? why not?
160
+ puts " #{ids.size} inscribe id(s)"
161
+ ids.each { |id| add(id) }
162
+ end
163
+
164
+ def _prepare_dir( dir )
165
+ ids = []
166
+
167
+ ## in html format
168
+ pages = Dir.glob( "#{dir}/**/*.html")
169
+ pages.each do |path|
170
+ ids += _prepare_html( path )
171
+ end
172
+
173
+ ### in csv format
174
+ datasets = Dir.glob( "#{dir}/**/*.csv")
175
+ datasets.each do |path|
176
+ ids += _prepare_csv( path )
177
+ end
178
+
179
+ ids
180
+ end
181
+
182
+ def add_dir( dir )
183
+ ids = _prepare_dir( dir )
184
+ puts " #{ids.size} inscribe id(s)"
185
+ ## turn into symbol (to make uniq work ??)
186
+ ids = ids.uniq
187
+ pp ids
188
+ puts " #{ids.size} inscribe id(s) - unique"
189
+ ids.each { |id| add(id) }
190
+ end
191
+
192
+
193
+
194
+ def read( id )
195
+ _read_inscribe( "#{@dir}/#{id[0,2]}/#{id[2..-1]}.meta.txt" )
196
+ end
197
+
198
+ def _read_inscribe( path )
199
+ read_headers( path )
200
+ end
201
+
202
+ end # class Cache
203
+ end # module Ordinals
@@ -5,8 +5,6 @@ class Sandbox
5
5
  def initialize( dir='./content' )
6
6
  @dir = dir
7
7
  @force = false
8
- @delay_in_s = 0.5 ## wait 0.5s before next (possible) request
9
- @requests = 0
10
8
  end
11
9
 
12
10
 
@@ -24,9 +22,7 @@ class Sandbox
24
22
  path = "#{@dir}/#{id}"
25
23
  if !@force && File.exist?( path )
26
24
  ## puts " in sandbox"
27
- else
28
- sleep( @delay_in_s ) if @delay_in_s && @requests > 0
29
-
25
+ else
30
26
  ## note: save text as blob - byte-by-byte as is (might be corrupt text)
31
27
  content = Ordinals.content( id )
32
28
  ## pp content
@@ -38,7 +34,6 @@ class Sandbox
38
34
  ## puts "data:"
39
35
  ## puts content.data
40
36
  write_blob( path, content.data )
41
- @requests += 1
42
37
  end
43
38
  end
44
39
 
@@ -0,0 +1,20 @@
1
+
2
+ module Ordinals
3
+ # sync version w/ sport.db n friends - why? why not?
4
+ MAJOR = 1 ## todo: namespace inside version or something - why? why not??
5
+ MINOR = 2
6
+ PATCH = 1
7
+ VERSION = [MAJOR,MINOR,PATCH].join('.')
8
+
9
+ def self.version
10
+ VERSION
11
+ end
12
+
13
+ def self.banner
14
+ "ordinals/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in >#{root}<"
15
+ end
16
+
17
+ def self.root
18
+ File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )
19
+ end
20
+ end
data/lib/ordinals.rb CHANGED
@@ -5,6 +5,49 @@ require 'nokogiri'
5
5
 
6
6
 
7
7
 
8
+ ### todo/fix:
9
+ ### move upstream - read_headers
10
+
11
+ ##
12
+ # note: key only supports a-z0-9 AND dash(-)
13
+ # no underscore(_) or dot(.)
14
+ #
15
+ # follow HTTP headers and domain names format
16
+ ##
17
+
18
+ HEADER_RX = /\A(?<key>[a-z][a-z0-9-]*)
19
+ :
20
+ [ ]*
21
+ (?<value>.+?) ## non-greedy
22
+ \z
23
+ /x
24
+
25
+
26
+ def read_headers( path )
27
+ txt = read_text( path )
28
+ h = {}
29
+ txt.each_line do |line|
30
+ line = line.strip
31
+ ## skip empty and comment lines
32
+ next if line.empty? || line.start_with?( '#' )
33
+
34
+ if m=HEADER_RX.match(line)
35
+ key = m[:key]
36
+ value = m[:value]
37
+
38
+ h[key] = value
39
+ else
40
+ puts "!! ERROR - parse error - no header pattern match for:"
41
+ puts line
42
+ exit 1
43
+ end
44
+ end
45
+ h
46
+ end
47
+
48
+
49
+
50
+
8
51
 
9
52
  module Ordinals
10
53
  class Configuration
@@ -43,6 +86,15 @@ module Ordinals
43
86
  self.chain = 'btc' unless defined?( @client )
44
87
  @client
45
88
  end
89
+
90
+ def delay_in_s
91
+ ## note - default to 1 (sec) if not set
92
+ self.delay_in_s = 1 unless defined?( @delay_in_s )
93
+ @delay_in_s
94
+ end
95
+ def delay_in_s=(value) @delay_in_s = value; end
96
+ alias_method :sleep, :delay_in_s ## add sleep alias (or wait) - why? why not?
97
+ alias_method :sleep=, :delay_in_s=
46
98
  end # class Configuration
47
99
 
48
100
 
@@ -76,16 +128,21 @@ module Ordinals
76
128
 
77
129
  ###################
78
130
  ### more convenience shortcuts
79
- def self.inscription( id ) client.inscription( id ); end
80
- def self.content( id ) client.content( id ); end
131
+ def self.inscription( num_or_id ) client.inscription( num_or_id ); end
132
+ def self.content( num_or_id ) client.content( num_or_id ); end
133
+
134
+ def self.inscription_ids( offset: ) client.inscription_ids( offset: offset ); end
135
+ def self.sub10k_ids() client.sub10k_ids; end
81
136
  end # module Ordinals
82
137
 
83
138
 
84
139
 
85
140
 
86
141
  ## our own code
142
+ require_relative 'ordinals/version'
87
143
  require_relative 'ordinals/api'
88
144
 
145
+ require_relative 'ordinals/cache'
89
146
  require_relative 'ordinals/sandbox' ## (blob) "flat" content cache by inscribe id (./content)
90
147
  require_relative 'ordinals/stats'
91
148
 
@@ -100,3 +157,7 @@ require_relative 'ordinals/recursive/generator'
100
157
  RcsvImage = RecursiveImage
101
158
  RcsvImageComposite = RecursiveImageComposite
102
159
 
160
+
161
+
162
+ # say hello
163
+ puts Ordinals.banner ## if defined?($RUBYCOCOS_DEBUG) && $RUBCOCOS_DEBUG
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ordinals
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-21 00:00:00.000000000 Z
11
+ date: 2023-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cocos
@@ -88,11 +88,13 @@ files:
88
88
  - Rakefile
89
89
  - lib/ordinals.rb
90
90
  - lib/ordinals/api.rb
91
+ - lib/ordinals/cache.rb
91
92
  - lib/ordinals/recursive/composite.rb
92
93
  - lib/ordinals/recursive/generator.rb
93
94
  - lib/ordinals/recursive/image.rb
94
95
  - lib/ordinals/sandbox.rb
95
96
  - lib/ordinals/stats.rb
97
+ - lib/ordinals/version.rb
96
98
  homepage: https://github.com/ordbase/ordbase
97
99
  licenses:
98
100
  - Public Domain