artbase 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,39 +0,0 @@
1
-
2
-
3
- class ImageCollection
4
-
5
- attr_reader :slug, :count
6
-
7
- def initialize( slug, count,
8
- image_base: ) # check: rename count to items or such - why? why not?
9
- @slug = slug
10
- @count = count
11
- @image_base = image_base
12
- end
13
-
14
- def download_images( range=(0...@count) )
15
- start = Time.now
16
- delay_in_s = 0.3
17
-
18
- range.each do |offset|
19
- image_src = @image_base.sub( '{id}', offset.to_s )
20
-
21
- puts "==> #{offset} - #{@slug}..."
22
-
23
- ## note: will auto-add format file extension (e.g. .png, .jpg)
24
- ## depending on http content type!!!!!
25
- copy_image( image_src, "./#{@slug}/image-i/#{offset}" )
26
-
27
- stop = Time.now
28
- diff = stop - start
29
-
30
- mins = diff / 60 ## todo - use floor or such?
31
- secs = diff % 60
32
- puts "up #{mins} mins #{secs} secs (total #{diff} secs)"
33
-
34
- puts "sleeping #{delay_in_s}s..."
35
- sleep( delay_in_s )
36
- end
37
- end
38
- end # class ImageCollection
39
-
@@ -1,297 +0,0 @@
1
-
2
-
3
- class Collection ## todo/check - change to OpenseaCollection or such - why? why not?
4
-
5
- attr_reader :slug, :count
6
-
7
- # check: rename count to items or such - why? why not?
8
- # default format to '24x24' - why? why not?
9
- def initialize( slug, count,
10
- meta_slugify: nil,
11
- image_pixelate: nil,
12
- patch: nil,
13
- exclude: [],
14
- format:,
15
- source: )
16
- @slug = slug
17
- @count = count
18
-
19
- @meta_slugify = meta_slugify
20
- @image_pixelate = image_pixelate
21
-
22
- @patch = patch
23
-
24
- @exclude = exclude
25
-
26
- @width, @height = _parse_dimension( format )
27
-
28
-
29
- ## note: allow multiple source formats / dimensions
30
- ### e.g. convert 512x512 into [ [512,512] ]
31
- ##
32
- source = [source] unless source.is_a?( Array )
33
- @sources = source.map { |dimension| _parse_dimension( dimension ) }
34
- end
35
-
36
- ## e.g. convert dimension (width x height) "24x24" or "24 x 24" to [24,24]
37
- def _parse_dimension( str )
38
- str.split( /x/i ).map { |str| str.strip.to_i }
39
- end
40
-
41
-
42
- def _image_pixelate( img )
43
- if @image_pixelate
44
- @image_pixelate.call( img )
45
- else
46
- @sources.each do |source_width, source_height|
47
- if img.width == source_width && img.height == source_height
48
- from = "#{source_width}x#{source_height}"
49
- to = "#{@width}x#{@height}"
50
- steps = (Image::DOwNSAMPLING_STEPS[ to ] || {})[ from ]
51
- if steps.nil?
52
- puts "!! ERROR - no sampling steps defined for #{from} to #{to}; sorry"
53
- exit 1
54
- end
55
-
56
- return img.pixelate( steps )
57
- end
58
- end
59
-
60
- puts "!! ERROR - unknown image dimension #{img.width}x#{img.height}; sorry"
61
- puts " supported source dimensions include: #{@sources.inspect}"
62
- exit 1
63
- end
64
- end
65
-
66
-
67
-
68
-
69
- def download_meta( range=(0...@count) )
70
- self.class.download_meta( range, @slug )
71
- end
72
-
73
- def download_images( range=(0...@count) )
74
- self.class.download_images( range, @slug )
75
- end
76
-
77
- def download( range=(0...@count) )
78
- download_meta( range )
79
- download_images( range )
80
- end
81
-
82
-
83
-
84
-
85
-
86
- def _meta_slugify_match( regex, meta, index )
87
- if m=regex.match( meta.name )
88
- captures = m.named_captures ## get named captures in match data as hash (keys as strings)
89
- # e.g.
90
- #=> {"num"=>"3"}
91
- #=> {"num"=>"498", "name"=>"Doge"}
92
- pp captures
93
-
94
- num = captures['num'] ? captures['num'].to_i( 10 ) : nil ## note: add base 10 (e.g. 015=>15)
95
- name = captures['name'] ? captures['name'].strip : nil
96
-
97
- slug = ''
98
- if num
99
- slug << "%06d" % num ## todo/check: always fill/zero-pad with six 000000's - why? why not?
100
- end
101
-
102
- if name
103
- slug << "-" if num ## add separator
104
- slug << slugify( name )
105
- end
106
- slug
107
- else
108
- nil ## note: return nil if no match / slug
109
- end
110
- end
111
-
112
- def _do_meta_slugify( meta_slugify, meta, index )
113
- if meta_slugify.is_a?( Regexp )
114
- _meta_slugify_match( meta_slugify, meta, index )
115
- elsif meta_slugify.is_a?( Proc )
116
- meta_slugify.call( meta, index )
117
- else
118
- raise ArgumentError, "meta_slugify - unsupported type: #{meta_slugify.class.name}"
119
- end
120
- end
121
-
122
-
123
- def _meta_slugify( meta, index )
124
- slug = nil
125
-
126
- if @meta_slugify.is_a?( Array )
127
- @meta_slugify.each do |meta_slugify|
128
- slug = _do_meta_slugify( meta_slugify, meta, index )
129
- return slug if slug ## note: short-circuit on first match
130
- ## use break instead of return - why? why not?
131
- end
132
- else ## assume object e.g. Regexp, Proc, etc.
133
- slug = _do_meta_slugify( @meta_slugify, meta, index )
134
- end
135
-
136
- ## do nothing
137
- if slug.nil?
138
- puts "!! ERROR - cannot find id in >#{meta.name}<:"
139
- pp meta
140
- exit 1
141
- end
142
-
143
- slug
144
- end
145
-
146
-
147
-
148
- def each_meta( range=(0...@count),
149
- exclude: true, &blk )
150
- range.each do |id| ## todo/fix: change id to index
151
- meta = OpenSea::Meta.read( "./#{@slug}/meta/#{id}.json" )
152
-
153
- ####
154
- # filter out/skip
155
- if exclude && @exclude.include?( meta.name )
156
- puts " skipping / exclude #{id} >#{meta.name}<..."
157
- next
158
- end
159
-
160
- blk.call( meta, id )
161
- end
162
- end
163
-
164
-
165
-
166
-
167
- def pixelate( range=(0...@count) )
168
-
169
- meta_slugs = Hash.new( 0 ) ## deduplicate (auto-add counter if duplicate)
170
-
171
- ### todo/fix: must read slugs starting at 0
172
- ### to work for deduplicate!!!!!!
173
-
174
-
175
- range.each do |id|
176
- meta = OpenSea::Meta.read( "./#{@slug}/meta/#{id}.json" )
177
-
178
- ####
179
- # filter out/skip
180
- if @exclude.include?( meta.name )
181
- puts " skipping / exclude #{id} >#{meta.name}<..."
182
- next
183
- end
184
-
185
- puts meta.name
186
-
187
-
188
- meta_slug = _meta_slugify( meta, id )
189
- count = meta_slugs[ meta_slug ] += 1
190
-
191
- meta_slug = "#{meta_slug}_(#{count})" if count > 1
192
-
193
-
194
- img = Image.read( "./#{@slug}/i/#{id}.png" )
195
-
196
- pix = _image_pixelate( img )
197
-
198
- path = "./#{@slug}/ii/#{meta_slug}.png"
199
- puts " saving to >#{path}<..."
200
- pix.save( path )
201
- end
202
- end
203
-
204
-
205
-
206
- ################################
207
- # private (static) helpers
208
- #
209
-
210
- def self.download_images( range, collection,
211
- original: false )
212
- start = Time.now
213
- delay_in_s = 0.3
214
-
215
- range.each do |offset|
216
- meta = OpenSea::Meta.read( "./#{collection}/meta/#{offset}.json" )
217
-
218
- puts "==> #{offset}.json - #{meta.name}"
219
-
220
- image_src = if original
221
- meta.image_original_url
222
- else
223
- meta.image_url
224
- end
225
-
226
- puts " >#{image_src}<"
227
- if image_src.nil?
228
- puts "!! ERROR - no image url found (use original: #{original}):"
229
- pp meta
230
- exit 1
231
- end
232
-
233
- ## note: use a different directory to avoid size confusion!!!
234
- img_slug = if original
235
- 'i_org'
236
- else
237
- 'i'
238
- end
239
-
240
- ## note: will auto-add format file extension (e.g. .png, .jpg)
241
- ## depending on http content type!!!!!
242
- copy_image( image_src, "./#{collection}/#{img_slug}/#{offset}" )
243
-
244
- stop = Time.now
245
- diff = stop - start
246
-
247
- mins = diff / 60 ## todo - use floor or such?
248
- secs = diff % 60
249
- puts "up #{mins} mins #{secs} secs (total #{diff} secs)"
250
-
251
- puts "sleeping #{delay_in_s}s..."
252
- sleep( delay_in_s )
253
- end
254
- end
255
-
256
-
257
- def self.download_meta( range, collection )
258
- start = Time.now
259
- delay_in_s = 0.3
260
-
261
- range.each do |offset|
262
-
263
- dest = "./#{collection}/meta/#{offset}.json"
264
- meta = nil
265
-
266
- puts "==> #{offset} / #{collection} (#{dest})..."
267
-
268
- data = OpenSea.assets( collection: collection,
269
- offset: offset )
270
- meta = OpenSea::Meta.new( data )
271
- puts " name: >#{meta.name}<"
272
- puts " image_url: >#{meta.image_url}<"
273
-
274
-
275
- ## make sure path exists
276
- dirname = File.dirname( dest )
277
- FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname )
278
-
279
- File.open( dest, "w:utf-8" ) do |f|
280
- f.write( JSON.pretty_generate( data ) )
281
- end
282
-
283
-
284
- stop = Time.now
285
- diff = stop - start
286
-
287
- mins = diff / 60 ## todo - use floor or such?
288
- secs = diff % 60
289
- puts "up #{mins} mins #{secs} secs (total #{diff} secs)"
290
-
291
- puts " sleeping #{delay_in_s}s..."
292
- sleep( delay_in_s )
293
- end
294
- end
295
-
296
-
297
- end # class Collection