Class: Ordinals::Collection

Inherits:
Object
  • Object
show all
Defined in:
lib/ordbase/collection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(slug) ⇒ Collection

Returns a new instance of Collection.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/ordbase/collection.rb', line 11

def initialize( slug )
    @slug = slug

    ## read config if present
    config_path = "./#{@slug}/collection.yml"
    if File.exist?( config_path )
      config = read_yaml( config_path )
      pp config

      @width, @height = _parse_dimension( config['format'] )

      ## note: allow multiple source formats / dimensions
      ### e.g. convert   512x512 into  [ [512,512] ]
      ##
      source = config['source']
      source = [source]  unless source.is_a?( Array )
      @sources = source.map { |dimension| _parse_dimension( dimension ) }
    end
end

Instance Attribute Details

#heightObject (readonly)

Returns the value of attribute height.



6
7
8
# File 'lib/ordbase/collection.rb', line 6

def height
  @height
end

#slugObject (readonly)

Returns the value of attribute slug.



6
7
8
# File 'lib/ordbase/collection.rb', line 6

def slug
  @slug
end

#sourcesObject (readonly)

Returns the value of attribute sources.



6
7
8
# File 'lib/ordbase/collection.rb', line 6

def sources
  @sources
end

#widthObject (readonly)

Returns the value of attribute width.



6
7
8
# File 'lib/ordbase/collection.rb', line 6

def width
  @width
end

Instance Method Details

#_parse_dimension(str) ⇒ Object

e.g. convert dimension (width x height) “24x24” or “24 x 24” to [24,24]



75
76
77
# File 'lib/ordbase/collection.rb', line 75

def _parse_dimension( str )
    str.split( /x/i ).map { |str| str.strip.to_i }
end

#convert_imagesObject



162
163
164
165
166
167
168
169
170
171
# File 'lib/ordbase/collection.rb', line 162

def convert_images
  Image.convert( image_dir, from: 'jpg',
                            to:   'png' )

  Image.convert( image_dir, from: 'gif',
                            to:   'png' )

  Image.convert( image_dir, from: 'webp',
                            to:   'png' )
end

#countObject Also known as: size



41
# File 'lib/ordbase/collection.rb', line 41

def count() ordinals.size; end

#download_imagesObject



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/ordbase/collection.rb', line 228

def download_images
  each_ordinal do |rec, i|
    id   = rec['id']
    num  = rec.has_key?('num') ? rec['num'].to_i(10) : i+1

    ##  note: add gif too (for check) - add more formats - why? why not?
    next if File.exist?( "#{image_dir}/#{num}.png" ) ||
            File.exist?( "#{image_dir}/#{num}.gif" ) ||
            File.exist?( "#{image_dir}/#{num}.jpg" )


    puts "==> downloading image ##{num}..."


    content = Ordinals.client.content( id )

      puts "  content_type: #{content.type}, content_length: #{content.length}"

      format = if content.type =~ %r{image/jpeg}i
                 'jpg'
               elsif content.type =~ %r{image/png}i
                'png'
               elsif content.type =~ %r{image/gif}i
                 'gif'
               elsif content.type =~ %r{image/webp}i
                 'webp'
               else
                 puts "!! ERROR:"
                 puts " unknown image format content type: >#{content.type}<"
                 exit 1
               end

      ## save image - using b(inary) mode
      write_blob( "#{image_dir}/#{num}.#{format}", content.blob )

      sleep( 1.0 )  ## sleep (delay_in_s)
  end
end

#download_metaObject

inscription metadata



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/ordbase/collection.rb', line 190

def download_meta   ## inscription metadata
  each_ordinal do |rec, i|
    id   = rec['id']
    num  = rec.has_key?('num') ? rec['num'].to_i(10) : i+1

    chain = Ordinals.config.chain
    path = "../ordinals.cache/#{chain}/#{id}.json"
    next if File.exist?( path )

    puts "==> downloading #{chain} inscription meta #{num} w/ id #{id}..."

    data = Ordinals.client.inscription( id )

    write_json( path, data )

    sleep( 1.0 )  ## sleep (delay_in_s)
  end
end

#dump_statsObject



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/ordbase/collection.rb', line 209

def dump_stats
  stats = InscriptionStats.new

  each_ordinal do |rec, i|
    id   = rec['id']

    chain = Ordinals.config.chain
    path = "../ordinals.cache/#{chain}/#{id}.json"

    data = read_json( path )
    stats.update( data )
  end

  pp stats.data
  puts
  puts stats.format
end

#each_image(&block) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ordbase/collection.rb', line 56

def each_image( &block )
  each_ordinal do |rec, i|
    id   = rec['id']
    num  = rec.has_key?('num') ? rec['num'].to_i(10) : i+1

    path = "./#{@slug}/#{@width}x#{@height}/#{num}.png"
    img = Image.read( path )

    block.call( img, num )
  end
end

#each_ordinal(&block) ⇒ Object



46
47
48
49
50
# File 'lib/ordbase/collection.rb', line 46

def each_ordinal( &block )
  ordinals.each_with_index do |rec, i|   ## pass along hash rec for now - why? why not?
    block.call( rec, i )
  end
end

#fix_imagesObject

todo - find a different names for resaving png images?



175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/ordbase/collection.rb', line 175

def fix_images   ## todo - find a different names for resaving png images?
  ##  "repair" png images
  ##    starting w/
  ##  - why?
  ##
  ## verify_signature! - ChunkyPNG::SignatureMismatch:
  ##  PNG signature not found,
  ##  found     "RIFF\\xFE\\b\\x00\\x00"
  ##  instead of "\\x89PNG\\r\\n\\x1A\\n"

  Image.convert( image_dir, from: 'png',
                            to:   'png' )
end

#image_dirObject



70
# File 'lib/ordbase/collection.rb', line 70

def image_dir()  "./#{@slug}/token-i";  end

#make_composite(limit: nil) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/ordbase/collection.rb', line 118

def make_composite( limit: nil )

  composite_count =  limit ? limit : count

  cols, rows = case composite_count
               when    10 then   [5,   2]
               when    12 then   [4,   3]
               when    15 then   [5,   3]
               when    20 then   [5,   4]
               when    40 then   [10,  4]
               when    50 then   [10,  5]
               when    69 then   [10,  7]
               when    80 then   [10,  8]
               when    88 then   [10,  9]
               when 98,99 then   [10,  10]
               when   100 then   [10,  10]
               when   101 then   [11,  10]
               when   111 then   [11,  11]
               when   130 then   [10,  13]
               when   512 then   [20,  26]
               else
                   raise ArgumentError, "sorry - unknown composite count #{composite_count} for now"
               end

  composite = ImageComposite.new( cols, rows,
                                  width:  @width,
                                  height: @height )


  image_count = 0
  each_image do |img, num|
    puts "==> #{num}"
    composite << img

    image_count += 1
    break   if image_count >= composite_count
  end


   composite.save( "./#{@slug}/tmp/#{@slug}.png" )
end

#ordinalsObject



32
33
34
35
36
37
38
39
# File 'lib/ordbase/collection.rb', line 32

def ordinals
   @ordinals ||= begin
                     recs = read_csv( "./#{@slug}/ordinals.csv" )
                     puts "  #{recs.size} record(s)"
                     recs
                 end
   @ordinals
end

#pixelateObject



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/ordbase/collection.rb', line 80

def pixelate
  each_ordinal do |rec, i|
    id   = rec['id']
    num  = rec.has_key?('num') ? rec['num'].to_i(10) : i+1

    outpath = "./#{@slug}/#{@width}x#{@height}/#{num}.png"
    next if File.exist?( outpath )

    path = "#{image_dir}/#{num}.png"
    puts "==> reading #{path}..."

    img = Image.read( path )
    puts "   #{img.width}x#{img.height}"

    ## check for source images
    if !@sources.include?( [img.width, img.height] )
      puts "  !! ERROR - unexpected image size; sorry - expected:"
      pp @sources
      exit 1
    end

    ## check for special case   source == format!!
    if [img.width,img.height] == [@width,@height]
      puts "   note: saving image as is - no downsampling"
      img.save( outpath )
    else
      steps_x = Image.calc_sample_steps( img.width, @width )
      steps_y = Image.calc_sample_steps( img.height, @height )

      img = img.sample( steps_x, steps_y )
      img.save( outpath )
    end
  end
end