ordinals 0.1.0 → 1.0.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: 8713aa7b98dcb5356b762898b13ab4539313ef8621f2930b5291519edd759f50
4
- data.tar.gz: 6c4a9f720237c5e6468eede3f7b69988ecbdcf5fd347749cd9f18dd9de0fdb6a
3
+ metadata.gz: 99bcfe173a347fb795174d2fc8a38ed2e8bde67089ae0340edda7c146592107c
4
+ data.tar.gz: e916e620469af7171250c630e09fbeb8c223eb9e197643e109127d07eed27519
5
5
  SHA512:
6
- metadata.gz: 803d2f9357b35101f2572767de7f7176966d077b2b87bef45b2cb6c1f90c80ec4513d71aad231e08ddc5a112683ac0c24139a40e832f714dac05b47039654b3f
7
- data.tar.gz: 64071daa9c9c4352174a4be0c5cce8a7ee5d407920c922f29cadf8d015ab5ce963cc922f665039bfa3397142383aeeef3cff4e8c4650ec96faec32a33f6bddf3
6
+ metadata.gz: d15fc49964cfe2473a23ce61f36bed070d31e722afcb2110dfa33e0452f68ec6653a668b986c17924f0ce7b9ad20d9e8c63f594d4622dc2feb72641352b25f3e
7
+ data.tar.gz: 421f3eec03fd8cddbd290edae6eaec5a3d37b1448ce3736242fb58a28f0802c6fea6eea0d2ab49b635957aee103ebb5d9bc010830d947ac849f77a2e1ddf0ab4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,3 @@
1
- ### 0.0.1 / 2023-02-11
1
+ ### 0.0.1 / 2023-03-23
2
2
 
3
3
  * Everything is new. First release
data/Manifest.txt CHANGED
@@ -2,6 +2,5 @@ CHANGELOG.md
2
2
  Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
- bin/ordbase
6
5
  lib/ordinals.rb
7
- lib/ordinals/collection.rb
6
+ lib/ordinals/api.rb
data/README.md CHANGED
@@ -1,155 +1,28 @@
1
1
  # ordinals
2
2
 
3
- ordinals gem - "right-clicker" (off-chain) ordinals (pixel art) machinery & helpers for Bitcoin & co.
3
+ ordinals gem - ordinals (inscription) api wrapper & helpers for Bitcoin, Litcoin, Dogecoin & co.
4
4
 
5
5
 
6
- * home :: [github.com/pixelartexchange/ordinals.sandbox](https://github.com/pixelartexchange/ordinals.sandbox)
7
- * bugs :: [github.com/pixelartexchange/ordinals.sandbox/issues](https://github.com/pixelartexchange/ordinals.sandbox/issues)
6
+ * home :: [github.com/pixelartexchange/artbase](https://github.com/pixelartexchange/artbase)
7
+ * bugs :: [github.com/pixelartexchange/artbase/issues](https://github.com/pixelartexchange/artbase/issues)
8
8
  * gem :: [rubygems.org/gems/ordinals](https://rubygems.org/gems/ordinals)
9
9
  * rdoc :: [rubydoc.info/gems/ordinals](http://rubydoc.info/gems/ordinals)
10
10
 
11
11
 
12
- ## Comand-Line Usage
12
+ ## Usage
13
13
 
14
- Let's use the 100 Ordinal Punks collection to try out the
15
- `ordbase` command-line tool shipping with the ordinals package.
16
14
 
17
- Tip: New to Ordinal Punks? For some background see [**Awesome 100 Ordinal Punks (Anno 2023) Notes - 24×24 Pixel Art on the (Bitcoin) Blockchain »**](https://github.com/cryptopunksnotdead/cryptopunks/tree/master/awesome-ordinalpunks)
18
15
 
19
16
 
20
- ### Step 0: Prepare A Tabular Dataset (List) Of All Ordinals w/ ID
21
17
 
22
- For now a manual step - prepare a list of all ordinals with id in the comma-separated values (.csv) tabular dataset format.
23
- Example - [ordinalpunks/ordinals.csv](https://github.com/pixelartexchange/ordinals.sandbox/blob/master/ordinalpunks/ordinals.csv):
24
18
 
25
- ``` csv
26
- num, id
27
- 1, 96d87d7e59d75ebc0e6144b09fdd96355fcdaa86fd098d64c46f19a424012bbei0
28
- 2, acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37i0
29
- 3, 0406654dffdd01a49794bd8531bf33721986cc7c6546f871962adee921a39a9di0
30
- 4, 2fe9bb034f60db694701acb23a76c3d7d5aba4328dbd315764f6ee406ba41786i0
31
- 5, dcfa240f2681d1e4a8948120a3a64567262e3c78d5497cb4e97351bfa836b638i0
32
- 6, 16df62c86321895df2b93236d103c935015ed77e189485be649ce2c7e6ac8a4ei0
33
- 7, 81e8d9159b8e9a27c692a5bb3ba18ca037757e94e975b53e175eaaeb2c52f15ai0
34
- 8, c2e15fe87c4b1fd61de65f2804858e6d1152b6316bcb9c2b39b69c9c21638f5di0
35
- 9, 3ed569f3a92ade9f1b47031eb2db2045e7dee3e00787954a88c67ed2ad9854bbi0
36
- ...
37
- ```
38
19
 
39
20
 
40
- ### Step 1: Download All Pixel Art Images Via Ordinals.com
41
-
42
- Use
43
-
44
- ```
45
- $ ordbase ordinalpunks image # or
46
- $ ordbase ordinalpunks img
47
- ```
48
-
49
- to download all images via the ordinals.com (web) service.
50
- All images get stored in the (temporary) `token-i/` directory.
51
- Resulting in:
52
-
53
- ```
54
- /ordinalpunks
55
- ordinals.csv
56
- /token-i
57
- 1.png
58
- 2.png
59
- 3.png
60
- ...
61
- ```
62
-
63
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinals/i/1.png)
64
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinals/i/2.png)
65
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinals/i/3.png)
66
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinals/i/4.png)
67
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinals/i/5.png)
68
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinals/i/6.png)
69
- ...
70
-
71
-
72
-
73
-
74
- ### Step 2: Downsample ("Pixelate") All Pixel Art Images
75
-
76
- Note: Most pixel art collections upload / inscribe images with a zoom.
77
- The ordinal punks, for example, use a 8x zoom factor for the 24×24px originals, thus,
78
- resulting in 192×192px.
79
-
80
-
81
- Add a ["artbase-compatible"](https://github.com/pixelartexchange/artbase) collection configuration file to lists the source format(s)
82
- and the minimal true pixel format.
83
- Example - [ordinalpunks/collection.yml](https://github.com/pixelartexchange/ordinals.sandbox/blob/master/ordinalpunks/collection.yml):
84
-
85
- ``` yaml
86
- slug: ordinalpunks
87
- count: 100
88
- format: 24x24
89
- source: 192x192
90
- offset: 1
91
- ```
92
-
93
- Use
94
-
95
- ```
96
- $ ordbase ordinalpunks pixelate # or
97
- $ ordbase ordinalpunks px
98
- ```
99
-
100
- to downsample ("pixelate") all images
101
- in the (temporary) `token-i/` directory.
102
- Resulting in a `24x24`/ directory with all images
103
- in the "minimal" `24x24` format:
104
-
105
- ```
106
- /ordinalpunks
107
- ordinals.csv
108
- collections.yml
109
- /24x24
110
- 1.png
111
- 2.png
112
- 3.png
113
- ...
114
- ```
115
-
116
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinalpunks/24x24/1.png)
117
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinalpunks/24x24/2.png)
118
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinalpunks/24x24/3.png)
119
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinalpunks/24x24/4.png)
120
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinalpunks/24x24/5.png)
121
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/ordinalpunks/24x24/6.png)
122
- ...
123
-
124
-
125
-
126
- ### Bonus: Step 3: Make An All-In-One Collect'Em All Composite Image
127
-
128
-
129
- Use
130
-
131
- ```
132
- $ ordbase ordinalpunks composite # or
133
- $ ordbase ordinalpunks comp
134
- ```
135
-
136
- to make an all-in-one image composite for the complete collection.
137
- Resulting in `/tmp/ordinalpunks.png` (~11kb).
138
-
139
-
140
- ![](https://github.com/pixelartexchange/ordinals.sandbox/raw/master/i/ordinalpunks.png)
141
-
142
-
143
- That's it for now.
144
-
145
-
146
-
147
-
148
- ## Bonus: More Ordinal Pixel Art Collections
21
+ ## Bonus: Ordinal Pixel Art Collections
149
22
 
150
23
 
151
24
  See the [**Ordinals (Pixel Art) Sandbox (& Cache)**](https://github.com/pixelartexchange/ordinals.sandbox)
152
- for more collections incl. Bitcoin Punks (24×24), Ordinal Mini Doges (24×24),
25
+ for collections incl. Ordinal Punks & Phunks (24×24), Bitcoin Punks (24×24), Ordinal Mini Doges (24×24), Ordinal Doggies (32×32),
153
26
  Extra Ordinal Women (32×32), Ordinal Penguins (35×35),
154
27
  Ordinal Birds (42×42), Bitcoin Bears (48×48) and much more.
155
28
 
@@ -157,6 +30,7 @@ Add your sandbox or "right-clicker" ordinal backup / archive / gallery here. Yes
157
30
 
158
31
 
159
32
 
33
+
160
34
  ## License
161
35
 
162
36
  The scripts are dedicated to the public domain.
@@ -165,6 +39,6 @@ Use it as you please with no restrictions whatsoever.
165
39
 
166
40
  ## Questions? Comments?
167
41
 
42
+ Post them over at the [Help & Support](https://github.com/geraldb/help) page. Thanks.
168
43
 
169
- Post them on the [D.I.Y. Punk (Pixel) Art reddit](https://old.reddit.com/r/DIYPunkArt). Thanks.
170
44
 
data/Rakefile CHANGED
@@ -10,12 +10,12 @@ end
10
10
 
11
11
  Hoe.spec 'ordinals' do
12
12
 
13
- self.version = '0.1.0'
13
+ self.version = '1.0.1'
14
14
 
15
- self.summary = 'ordinals gem - "right-clicker" (off-chain) ordinals (pixel art) machinery & helpers for Bitcoin & co.'
15
+ self.summary = 'ordinals gem - ordinals (inscription) api wrapper & helpers for Bitcoin, Litecoin, Dogecoin & co.'
16
16
  self.description = summary
17
17
 
18
- self.urls = { home: 'https://github.com/pixelartexchange/ordinals.sandbox' }
18
+ self.urls = { home: 'https://github.com/pixelartexchange/artbase' }
19
19
 
20
20
  self.author = 'Gerald Bauer'
21
21
  self.email = 'wwwmake@googlegroups.com'
@@ -26,7 +26,7 @@ Hoe.spec 'ordinals' do
26
26
 
27
27
  self.extra_deps = [
28
28
  ['cocos'],
29
- ['pixelart'],
29
+ ['nokogiri'], ## required / used by api support (html parsing)
30
30
  ]
31
31
 
32
32
  self.licenses = ['Public Domain']
@@ -0,0 +1,224 @@
1
+
2
+
3
+ module Ordinals
4
+
5
+
6
+ class Api ## change/rename Api to Client - why? why not?
7
+ def self.litecoin
8
+ @litecoin ||= new( 'https://litecoin.earlyordies.com' )
9
+ @litecoin
10
+ end
11
+
12
+ def self.bitcoin
13
+ @bitcoin ||= new( 'https://ordinals.com' )
14
+ @bitcoin
15
+ end
16
+ ## todo: add ltc and btc alias - why? why not?
17
+
18
+ def self.dogecoin
19
+ ## note: "doginals" call inscriptions
20
+ ## shibescriptions
21
+ @dogecoin ||= new( 'https://doginals.com', inscription: 'shibescription' )
22
+ @dogecoin
23
+ end
24
+
25
+
26
+ def initialize( base, inscription: 'inscription' )
27
+ @base = base
28
+ @inscription = inscription
29
+ end
30
+
31
+
32
+ ###
33
+ # use a struct-like content class - why? why not?
34
+ class Content
35
+ attr_reader :data,
36
+ :type,
37
+ :length
38
+ def initialize( data, type, length )
39
+ @data = data
40
+ @type = type
41
+ @length = length
42
+ end
43
+
44
+ alias_method :blob, :data
45
+ end ## (nested) class Content
46
+
47
+
48
+
49
+ def content( id )
50
+ src = "#{@base}/content/#{id}"
51
+ res = get( src )
52
+
53
+ content_type = res.content_type
54
+ content_length = res.content_length
55
+
56
+ ## note - content_length -- returns an integer (number)
57
+ ## puts "content_length:"
58
+ ## print content_length.inspect
59
+ ## print " - #{content_length.class.name}\n"
60
+
61
+ content = Content.new(
62
+ res.blob,
63
+ content_type,
64
+ content_length )
65
+ content
66
+ end
67
+
68
+
69
+ =begin
70
+ <dl>
71
+ <dt>id</dt>
72
+ <dd class=monospace>d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2i0</dd>
73
+ <dt>address</dt>
74
+ <dd class=monospace>bc1pqapcyswesvccgqsmuncd96ylghs9juthqeshdr8smmh9w7azn8zsghjjar</dd>
75
+ <dt>output value</dt>
76
+ <dd>10000</dd>
77
+ <dt>sat</dt>
78
+ <dd><a href=/sat/1320953397332258>1320953397332258</a></dd>
79
+ <dt>preview</dt>
80
+ <dd><a href=/preview/d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2i0>link</a></dd>
81
+ <dt>content</dt>
82
+ <dd><a href=/content/d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2i0>link</a></dd>
83
+ <dt>content length</dt>
84
+ <dd>71997 bytes</dd>
85
+ <dt>content type</dt>
86
+ <dd>text/plain;charset=utf-8</dd>
87
+ <dt>timestamp</dt>
88
+ <dd><time>2023-02-11 21:39:00 UTC</time></dd>
89
+ <dt>genesis height</dt>
90
+ <dd><a href=/block/776090>776090</a></dd>
91
+ <dt>genesis fee</dt>
92
+ <dd>273630</dd>
93
+ <dt>genesis transaction</dt>
94
+ <dd><a class=monospace href=/tx/d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2>d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2</a></dd>
95
+ <dt>location</dt>
96
+ <dd class=monospace>d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2:0:0</dd>
97
+ <dt>output</dt>
98
+ <dd><a class=monospace href=/output/d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2:0>d026ac5994f698dba475681359b6c29d6d39a895484b95e06b7ae49921d80df2:0</a></dd>
99
+ <dt>offset</dt>
100
+ <dd>0</dd>
101
+ </dl>
102
+
103
+ <dl>
104
+ <dt>id</dt>
105
+ <dd class=monospace>acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37i0</dd>
106
+ <dt>address</dt>
107
+ <dd class=monospace>bc1qx3scwushtwenxtxlnjet4x2w5vg35etdtse5u0</dd>
108
+ <dt>output value</dt>
109
+ <dd>8020</dd>
110
+ <dt>sat</dt>
111
+ <dd><a href=/sat/1883186433806857>1883186433806857</a></dd>
112
+ <dt>preview</dt>
113
+ <dd><a href=/preview/acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37i0>link</a></dd>
114
+ <dt>content</dt>
115
+ <dd><a href=/content/acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37i0>link</a></dd>
116
+ <dt>content length</dt>
117
+ <dd>529 bytes</dd>
118
+ <dt>content type</dt>
119
+ <dd>image/png</dd>
120
+ <dt>timestamp</dt>
121
+ <dd><time>2023-01-31 19:34:47 UTC</time></dd>
122
+ <dt>genesis height</dt>
123
+ <dd><a href=/block/774489>774489</a></dd>
124
+ <dt>genesis fee</dt>
125
+ <dd>5340</dd>
126
+ <dt>genesis transaction</dt>
127
+ <dd><a class=monospace href=/tx/acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37>acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37</a></dd>
128
+ <dt>location</dt>
129
+ <dd class=monospace>6630ff2153985504b180fc16721d559a4cecdc66f4be6acf33509ec2100c0aa5:0:0</dd>
130
+ <dt>output</dt>
131
+ <dd><a class=monospace href=/output/6630ff2153985504b180fc16721d559a4cecdc66f4be6acf33509ec2100c0aa5:0>6630ff2153985504b180fc16721d559a4cecdc66f4be6acf33509ec2100c0aa5:0</a></dd>
132
+ <dt>offset</dt>
133
+ <dd>0</dd>
134
+ </dl>
135
+
136
+
137
+
138
+ <title>Inscription 407</title>
139
+
140
+ id =
141
+ genesis transaction + offset ???
142
+
143
+ genesis transaction: acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37
144
+ id: acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37i0
145
+ address: bc1qx3scwushtwenxtxlnjet4x2w5vg35etdtse5u0
146
+ output value: 8020
147
+ sat: 1883186433806857
148
+ content length: 529 bytes
149
+ content type: image/png
150
+ timestamp: 2023-01-31 19:34:47 UTC
151
+ genesis height: 774489
152
+ genesis fee: 5340
153
+ genesis transaction: acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37>acda637db995df796b35035fd978cc1a947f1e6fd5215968da88b7e38a7e4b37
154
+ location: 6630ff2153985504b180fc16721d559a4cecdc66f4be6acf33509ec2100c0aa5:0:0
155
+ output: 6630ff2153985504b180fc16721d559a4cecdc66f4be6acf33509ec2100c0aa5:0
156
+ offset: 0
157
+
158
+ =end
159
+
160
+ def inscription( id )
161
+ src = "#{@base}/#{@inscription}/#{id}"
162
+ res = get( src )
163
+
164
+ data = _parse_inscription( res.text )
165
+ data
166
+ end
167
+
168
+
169
+ def _parse_inscription( html )
170
+ doc = Nokogiri::HTML( html )
171
+
172
+ items = []
173
+
174
+ title = doc.css( 'head title' )
175
+ items << ['title', title.text]
176
+
177
+
178
+ dls = doc.css( 'body dl' )
179
+ dls[0].css( 'dt,dd' ).each do |el|
180
+ if el.name == 'dt'
181
+ items << [el.text]
182
+ elsif el.name == 'dd'
183
+ items[-1] << el.text
184
+ else
185
+ puts "!! ERROR - unexpected tag; expected dd|dl; got: #{el.name}"
186
+ exit 1
187
+ end
188
+ end
189
+ items
190
+
191
+ ## convert to hash
192
+ ## and check for duplicate
193
+ data = {}
194
+ items.each do |k,v|
195
+ k = k.strip
196
+ v = v.strip
197
+ if data.has_key?( k )
198
+ puts "!! ERROR - duplicate key >#{k}< in:"
199
+ pp items
200
+ exit 1
201
+ end
202
+ data[ k ] = v
203
+ end
204
+ data
205
+ end
206
+
207
+
208
+ def get( src )
209
+ res = Webclient.get( src )
210
+ if res.status.ok?
211
+ res
212
+ else
213
+ puts "!! ERROR - HTTP #{res.status.code} #{res.status.message} - failed web request >#{src}<; sorry"
214
+ exit 1
215
+ end
216
+ end
217
+ end # class Api
218
+
219
+ ##
220
+ ## add convenience alias
221
+ API = Api
222
+
223
+ end ## module Ordinals
224
+
data/lib/ordinals.rb CHANGED
@@ -1,95 +1,81 @@
1
-
2
1
  require 'cocos'
3
- require 'pixelart'
4
-
5
- require 'optparse'
6
2
 
3
+ ## note: add nokogiri for api (html parsing)
4
+ require 'nokogiri'
7
5
 
8
6
 
9
- ## our own code
10
- require_relative 'ordinals/collection'
11
-
12
7
 
13
8
 
14
9
  module Ordinals
15
- class Tool
16
-
17
- def self.main( args=ARGV )
18
- puts "==> welcome to ordinals/ordbase tool with args:"
19
- pp args
20
-
21
- options = {
22
- }
23
-
24
- parser = OptionParser.new do |opts|
25
-
26
- opts.on("-h", "--help", "Prints this help") do
27
- puts opts
28
- exit
29
- end
10
+ class Configuration
11
+
12
+ #######################
13
+ ## accessors
14
+ def chain=(value)
15
+ if value.is_a?( String ) || value.is_a?( Symbol )
16
+ case value.downcase.to_s
17
+ when 'btc', 'bitcoin', 'bitcon'
18
+ @chain = 'btc'
19
+ @client = Ordinals::Api.bitcoin
20
+ when 'ltc', 'litecoin', 'litecon'
21
+ @chain = 'ltc'
22
+ @client = Ordinals::Api.litecoin
23
+ when 'doge', 'dogecoin', 'dogecon'
24
+ @chain = 'doge'
25
+ @client = Ordinals::Api.dogecoin
26
+ else
27
+ raise ArgumentError, "unknown chain - expected btc | ltc | doge; got #{value}"
28
+ end
29
+ else
30
+ raise ArgumentError, "only string or symbol supported for now; sorry - got: #{value.inspect} : #{value.class.name}"
31
+ end
30
32
  end
31
33
 
32
- parser.parse!( args )
33
- puts "options:"
34
- pp options
35
-
36
- puts "args:"
37
- pp args
38
-
39
- if args.size < 1
40
- puts "!! ERROR - no collection found - use <collection> <command>..."
41
- puts ""
42
- exit
34
+ def chain
35
+ ## note - default to btc/bitcon if not set
36
+ self.chain = 'btc' unless defined?( @chain )
37
+ @chain
43
38
  end
44
39
 
45
- slug = args[0]
46
- command = args[1] || 'image'
47
-
48
- if ['i','img', 'image'].include?( command )
49
- do_download_images( slug )
50
- elsif ['conv','convert'].include?( command )
51
- do_convert_images( slug )
52
- elsif ['px','pixelate' ].include?( command )
53
- do_pixelate( slug )
54
- elsif ['comp','composite' ].include?( command )
55
- do_make_composite( slug )
56
- else
57
- puts "!! ERROR - unknown command >#{command}<, sorry"
40
+ ## note: read-only for now - why? why not?
41
+ def client
42
+ ## note - default to btc/bitcon if not set
43
+ self.chain = 'btc' unless defined?( @client )
44
+ @client
58
45
  end
59
-
60
- puts "bye"
61
- end
46
+ end # class Configuration
62
47
 
63
48
 
49
+ ## lets you use
50
+ ## Ordinals.configure do |config|
51
+ ## config.chain = :btc
52
+ ## end
53
+ def self.configure() yield( config ); end
54
+ def self.config() @config ||= Configuration.new; end
64
55
 
65
- def self.do_download_images( slug )
66
- puts "==> download images for collection >#{slug}<..."
67
-
68
- col = Collection.new( slug )
69
- col.download_images
70
- end
56
+ ## add some convenience shortcut helpers (no config. required) - why? why not?
57
+ def self.client() config.client; end
58
+ def self.chain() config.chain; end
71
59
 
60
+ def self.btc?() config.chain == 'btc'; end
61
+ def self.ltc?() config.chain == 'ltc'; end
62
+ def self.doge?() config.chain == 'doge'; end
63
+ class << self
64
+ alias_method :bitcoin?, :btc?
65
+ alias_method :bitcon?, :btc?
72
66
 
73
- def self.do_convert_images( slug )
74
- puts "==> convert images for collection >#{slug}<..."
67
+ alias_method :litecoin?, :ltc?
68
+ alias_method :litecon?, :ltc?
75
69
 
76
- col = Collection.new( slug )
77
- col.convert_images
70
+ alias_method :dogecoin?, :doge?
71
+ alias_method :dogecon?, :doge?
78
72
  end
73
+ end # module Ordinals
79
74
 
80
- def self.do_pixelate( slug )
81
- puts "==> downsample / pixelate images for collection >#{slug}<..."
82
75
 
83
- col = Collection.new( slug )
84
- col.pixelate
85
- end
86
76
 
87
- def self.do_make_composite( slug )
88
- puts "==> make composite for collection >#{slug}<..."
89
77
 
90
- col = Collection.new( slug )
91
- col.make_composite
92
- end
78
+ ## our own code
79
+ require_relative 'ordinals/api'
80
+
93
81
 
94
- end # class Tool
95
- end # module Ordinals
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: 0.1.0
4
+ version: 1.0.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-02-13 00:00:00.000000000 Z
11
+ date: 2023-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cocos
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: pixelart
28
+ name: nokogiri
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -72,11 +72,10 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '3.23'
75
- description: ordinals gem - "right-clicker" (off-chain) ordinals (pixel art) machinery
76
- & helpers for Bitcoin & co.
75
+ description: ordinals gem - ordinals (inscription) api wrapper & helpers for Bitcoin,
76
+ Litecoin, Dogecoin & co.
77
77
  email: wwwmake@googlegroups.com
78
- executables:
79
- - ordbase
78
+ executables: []
80
79
  extensions: []
81
80
  extra_rdoc_files:
82
81
  - CHANGELOG.md
@@ -87,10 +86,9 @@ files:
87
86
  - Manifest.txt
88
87
  - README.md
89
88
  - Rakefile
90
- - bin/ordbase
91
89
  - lib/ordinals.rb
92
- - lib/ordinals/collection.rb
93
- homepage: https://github.com/pixelartexchange/ordinals.sandbox
90
+ - lib/ordinals/api.rb
91
+ homepage: https://github.com/pixelartexchange/artbase
94
92
  licenses:
95
93
  - Public Domain
96
94
  metadata: {}
@@ -114,6 +112,6 @@ requirements: []
114
112
  rubygems_version: 3.3.7
115
113
  signing_key:
116
114
  specification_version: 4
117
- summary: ordinals gem - "right-clicker" (off-chain) ordinals (pixel art) machinery
118
- & helpers for Bitcoin & co.
115
+ summary: ordinals gem - ordinals (inscription) api wrapper & helpers for Bitcoin,
116
+ Litecoin, Dogecoin & co.
119
117
  test_files: []
data/bin/ordbase DELETED
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- ###################
4
- # == DEV TIPS:
5
- #
6
- # For local testing run like:
7
- #
8
- # ruby -Ilib bin/ordbase
9
- #
10
- # Set the executable bit in Linux. Example:
11
- #
12
- # % chmod a+x bin/ordbase
13
- #
14
-
15
- require 'ordinals'
16
-
17
- Ordinals::Tool.main
@@ -1,194 +0,0 @@
1
-
2
- module Ordinals
3
-
4
-
5
- class Collection
6
- attr_reader :slug,
7
- :width, :height,
8
- :sources
9
-
10
-
11
- def initialize( slug )
12
- @slug = slug
13
-
14
- ## read config if present
15
- config_path = "./#{@slug}/collection.yml"
16
- if File.exist?( config_path )
17
- config = read_yaml( config_path )
18
- pp config
19
-
20
- @width, @height = _parse_dimension( config['format'] )
21
-
22
- ## note: allow multiple source formats / dimensions
23
- ### e.g. convert 512x512 into [ [512,512] ]
24
- ##
25
- source = config['source']
26
- source = [source] unless source.is_a?( Array )
27
- @sources = source.map { |dimension| _parse_dimension( dimension ) }
28
- end
29
- end
30
-
31
-
32
- def ordinals
33
- @ordinals ||= begin
34
- recs = read_csv( "./#{@slug}/ordinals.csv" )
35
- puts " #{recs.size} record(s)"
36
- recs
37
- end
38
- @ordinals
39
- end
40
-
41
- def count() ordinals.size; end
42
- alias_method :size, :count
43
-
44
-
45
-
46
- def each_ordinal( &block )
47
- ordinals.each do |rec| ## pass along hash rec for now - why? why not?
48
- block.call( rec )
49
- end
50
- end
51
-
52
- ## add each_source_image or each_token_image or each_original_image or such - why? why not??
53
-
54
-
55
-
56
- def each_image( &block )
57
- each_ordinal do |rec|
58
- id = rec['id']
59
- num = rec['num'].to_i(10)
60
-
61
- path = "./#{@slug}/#{@width}x#{@height}/#{num}.png"
62
- img = Image.read( path )
63
-
64
- block.call( img, num )
65
- end
66
- end
67
-
68
-
69
-
70
- def image_dir() "./#{@slug}/token-i"; end
71
-
72
-
73
-
74
- ## e.g. convert dimension (width x height) "24x24" or "24 x 24" to [24,24]
75
- def _parse_dimension( str )
76
- str.split( /x/i ).map { |str| str.strip.to_i }
77
- end
78
-
79
-
80
- def pixelate
81
- each_ordinal do |rec|
82
- id = rec['id']
83
- num = rec['num']
84
-
85
- outpath = "./#{@slug}/#{@width}x#{@height}/#{num}.png"
86
- next if File.exist?( outpath )
87
-
88
- path = "#{image_dir}/#{num}.png"
89
- puts "==> reading #{path}..."
90
-
91
- img = Image.read( path )
92
- puts " #{img.width}x#{img.height}"
93
-
94
- ## check for source images
95
- if !@sources.include?( [img.width, img.height] )
96
- puts " !! ERROR - unexpected image size; sorry - expected:"
97
- pp @sources
98
- exit 1
99
- end
100
-
101
- ## check for special case source == format!!
102
- if [img.width,img.height] == [@width,@height]
103
- puts " note: saving image as is - no downsampling"
104
- img.save( outpath )
105
- else
106
- steps_x = Image.calc_sample_steps( img.width, @width )
107
- steps_y = Image.calc_sample_steps( img.height, @height )
108
-
109
- img = img.sample( steps_x, steps_y )
110
- img.save( outpath )
111
- end
112
- end
113
- end
114
-
115
-
116
- def make_composite
117
- cols, rows = case count
118
- when 10 then [5, 2]
119
- when 15 then [5, 3]
120
- when 69 then [10, 7]
121
- when 99 then [10, 10]
122
- when 100 then [10, 10]
123
- when 111 then [11, 11]
124
- else
125
- raise ArgumentError, "sorry - unknown composite count #{count} for now"
126
- end
127
-
128
- composite = ImageComposite.new( cols, rows,
129
- width: @width,
130
- height: @height )
131
-
132
-
133
- each_image do |img, num|
134
- puts "==> #{num}"
135
- composite << img
136
- end
137
-
138
- composite.save( "./#{@slug}/tmp/#{@slug}.png" )
139
- end
140
-
141
-
142
-
143
- def convert_images
144
- ## todo: check for gifs too - why? why not?
145
- Image.convert( image_dir, from: 'jpg',
146
- to: 'png' )
147
- end
148
-
149
-
150
- def download_images
151
- each_ordinal do |rec|
152
- id = rec['id']
153
- num = rec['num']
154
-
155
- next if File.exist?( "#{image_dir}/#{num}.png" )
156
-
157
- puts "==> downloading image ##{num}..."
158
-
159
- image_url = "https://ordinals.com/content/#{id}"
160
-
161
- res = Webclient.get( image_url )
162
-
163
- if res.status.ok?
164
- content_type = res.content_type
165
- content_length = res.content_length
166
-
167
- puts " content_type: #{content_type}, content_length: #{content_length}"
168
-
169
- format = if content_type =~ %r{image/jpeg}i
170
- 'jpg'
171
- elsif content_type =~ %r{image/png}i
172
- 'png'
173
- elsif content_type =~ %r{image/gif}i
174
- 'gif'
175
- else
176
- puts "!! ERROR:"
177
- puts " unknown image format content type: >#{content_type}<"
178
- exit 1
179
- end
180
-
181
- ## save image - using b(inary) mode
182
- write_blob( "#{image_dir}/#{num}.#{format}", res.blob )
183
-
184
- sleep( 1.0 ) ## sleep (delay_in_s)
185
- else
186
- puts "!! ERROR - failed to download image; sorry - #{res.status.code} #{res.status.message}"
187
- exit 1
188
- end
189
- end
190
- end
191
-
192
- end # class Collection
193
- end # module Ordinals
194
-