artbase 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,149 +1,168 @@
1
-
2
-
3
-
4
- def slugify( name )
5
- name.downcase.gsub( /[^a-z0-9 ()$_-]/ ) do |_|
6
- puts " !! WARN: asciify - found (and removing) non-ascii char >#{Regexp.last_match}<"
7
- '' ## remove - use empty string
8
- end.gsub( ' ', '_')
9
- end
10
-
11
-
12
-
13
-
14
- def convert_images( collection, from: 'jpg',
15
- to: 'png' )
16
- files = Dir.glob( "./#{collection}/i/*.#{from}" )
17
- puts "==> converting #{files.size} image(s) from #{from} to #{to}"
18
-
19
- files.each_with_index do |file,i|
20
- dirname = File.dirname( file )
21
- extname = File.extname( file )
22
- basename = File.basename( file, extname )
23
-
24
- cmd = "magick convert #{dirname}/#{basename}.#{from} #{dirname}/#{basename}.#{to}"
25
-
26
- puts " [#{i+1}/#{files.size}] - #{cmd}"
27
- system( cmd )
28
-
29
- if from == 'gif'
30
- ## assume multi-images for gif
31
- ## save image-0.png to image.png
32
- path0 = "#{dirname}/#{basename}-0.#{to}"
33
- path = "#{dirname}/#{basename}.#{to}"
34
-
35
- puts " saving #{path0} to #{path}..."
36
-
37
- blob = File.open( path0, 'rb' ) { |f| f.read }
38
- File.open( path, 'wb' ) { |f| f.write( blob ) }
39
- end
40
- end
41
- end
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
- def copy_json( src, dest )
51
- uri = URI.parse( src )
52
-
53
- http = Net::HTTP.new( uri.host, uri.port )
54
-
55
- puts "[debug] GET #{uri.request_uri} uri=#{uri}"
56
-
57
- headers = { 'User-Agent' => "ruby v#{RUBY_VERSION}" }
58
-
59
-
60
- request = Net::HTTP::Get.new( uri.request_uri, headers )
61
- if uri.instance_of? URI::HTTPS
62
- http.use_ssl = true
63
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
64
- end
65
-
66
- response = http.request( request )
67
-
68
- if response.code == '200'
69
- puts "#{response.code} #{response.message}"
70
- puts " content_type: #{response.content_type}, content_length: #{response.content_length}"
71
-
72
- text = response.body.to_s
73
- text = text.force_encoding( Encoding::UTF_8 )
74
-
75
- data = JSON.parse( text )
76
-
77
- File.open( dest, "w:utf-8" ) do |f|
78
- f.write( JSON.pretty_generate( data ) )
79
- end
80
- else
81
- puts "!! error:"
82
- puts "#{response.code} #{response.message}"
83
- exit 1
84
- end
85
- end
86
-
87
-
88
- def copy_image( src, dest,
89
- dump_headers: false )
90
- uri = URI.parse( src )
91
-
92
- http = Net::HTTP.new( uri.host, uri.port )
93
-
94
- puts "[debug] GET #{uri.request_uri} uri=#{uri}"
95
-
96
- headers = { 'User-Agent' => "ruby v#{RUBY_VERSION}" }
97
-
98
- request = Net::HTTP::Get.new( uri.request_uri, headers )
99
- if uri.instance_of? URI::HTTPS
100
- http.use_ssl = true
101
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
102
- end
103
-
104
- response = http.request( request )
105
-
106
- if response.code == '200'
107
- puts "#{response.code} #{response.message}"
108
-
109
- content_type = response.content_type
110
- content_length = response.content_length
111
- puts " content_type: #{content_type}, content_length: #{content_length}"
112
-
113
- if dump_headers ## for debugging dump headers
114
- headers = response.each_header.to_h
115
- puts "htttp respone headers:"
116
- pp headers
117
- end
118
-
119
-
120
- format = if content_type =~ %r{image/jpeg}i
121
- 'jpg'
122
- elsif content_type =~ %r{image/png}i
123
- 'png'
124
- elsif content_type =~ %r{image/gif}i
125
- 'gif'
126
- else
127
- puts "!! error:"
128
- puts " unknown image format content type: >#{content_type}<"
129
- exit 1
130
- end
131
-
132
- ## make sure path exits - autocreate dirs
133
- ## make sure path exists
134
- dirname = File.dirname( "#{dest}.#{format}" )
135
- FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname )
136
-
137
- File.open( "#{dest}.#{format}", 'wb' ) do |f|
138
- f.write( response.body )
139
- end
140
- else
141
- puts "!! error:"
142
- puts "#{response.code} #{response.message}"
143
- exit 1
144
- end
145
- end
146
-
147
-
148
-
149
-
1
+
2
+
3
+
4
+ def slugify( name )
5
+ name.downcase.gsub( /[^a-z0-9 ()$_-]/ ) do |_|
6
+ puts " !! WARN: asciify - found (and removing) non-ascii char >#{Regexp.last_match}<"
7
+ '' ## remove - use empty string
8
+ end.gsub( ' ', '_')
9
+ end
10
+
11
+
12
+
13
+
14
+ def convert_images( collection, from: 'jpg',
15
+ to: 'png',
16
+ dir: 'i',
17
+ overwrite: true )
18
+ files = Dir.glob( "./#{collection}/#{dir}/*.#{from}" )
19
+ puts "==> converting #{files.size} image(s) from #{from} to #{to}"
20
+
21
+ files.each_with_index do |file,i|
22
+ dirname = File.dirname( file )
23
+ extname = File.extname( file )
24
+ basename = File.basename( file, extname )
25
+
26
+ ## skip convert if target / dest file already exists
27
+ next if overwrite == false && File.exist?( "#{dirname}/#{basename}.#{to}" )
28
+
29
+
30
+ cmd = "magick convert #{dirname}/#{basename}.#{from} #{dirname}/#{basename}.#{to}"
31
+
32
+ puts " [#{i+1}/#{files.size}] - #{cmd}"
33
+ system( cmd )
34
+
35
+ if from == 'gif'
36
+ ## assume multi-images for gif
37
+ ## save image-0.png to image.png
38
+ path0 = "#{dirname}/#{basename}-0.#{to}"
39
+ path = "#{dirname}/#{basename}.#{to}"
40
+
41
+ puts " saving #{path0} to #{path}..."
42
+
43
+ blob = File.open( path0, 'rb' ) { |f| f.read }
44
+ File.open( path, 'wb' ) { |f| f.write( blob ) }
45
+ end
46
+ end
47
+ end
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+ def copy_json( src, dest )
57
+ uri = URI.parse( src )
58
+
59
+ http = Net::HTTP.new( uri.host, uri.port )
60
+
61
+ puts "[debug] GET #{uri.request_uri} uri=#{uri}"
62
+
63
+ headers = { 'User-Agent' => "ruby v#{RUBY_VERSION}" }
64
+
65
+
66
+ request = Net::HTTP::Get.new( uri.request_uri, headers )
67
+ if uri.instance_of? URI::HTTPS
68
+ http.use_ssl = true
69
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
70
+ end
71
+
72
+ response = http.request( request )
73
+
74
+ if response.code == '200'
75
+ puts "#{response.code} #{response.message}"
76
+ puts " content_type: #{response.content_type}, content_length: #{response.content_length}"
77
+
78
+ text = response.body.to_s
79
+ text = text.force_encoding( Encoding::UTF_8 )
80
+
81
+ data = JSON.parse( text )
82
+
83
+ File.open( dest, "w:utf-8" ) do |f|
84
+ f.write( JSON.pretty_generate( data ) )
85
+ end
86
+ else
87
+ puts "!! error:"
88
+ puts "#{response.code} #{response.message}"
89
+ exit 1
90
+ end
91
+ end
92
+
93
+
94
+ def copy_image( src, dest,
95
+ dump_headers: false )
96
+ uri = URI.parse( src )
97
+
98
+ http = Net::HTTP.new( uri.host, uri.port )
99
+
100
+ puts "[debug] GET #{uri.request_uri} uri=#{uri}"
101
+
102
+ headers = { 'User-Agent' => "ruby v#{RUBY_VERSION}" }
103
+
104
+ request = Net::HTTP::Get.new( uri.request_uri, headers )
105
+ if uri.instance_of? URI::HTTPS
106
+ http.use_ssl = true
107
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
108
+ end
109
+
110
+ response = http.request( request )
111
+
112
+ if response.code == '200'
113
+ puts "#{response.code} #{response.message}"
114
+
115
+ content_type = response.content_type
116
+ content_length = response.content_length
117
+ puts " content_type: #{content_type}, content_length: #{content_length}"
118
+
119
+ if dump_headers ## for debugging dump headers
120
+ headers = response.each_header.to_h
121
+ puts "htttp respone headers:"
122
+ pp headers
123
+ end
124
+
125
+
126
+ format = if content_type =~ %r{image/jpeg}i
127
+ 'jpg'
128
+ elsif content_type =~ %r{image/png}i
129
+ 'png'
130
+ elsif content_type =~ %r{image/gif}i
131
+ 'gif'
132
+ elsif content_type =~ %r{image/svg}i
133
+ 'svg'
134
+ else
135
+ puts "!! error:"
136
+ puts " unknown image format content type: >#{content_type}<"
137
+ exit 1
138
+ end
139
+
140
+ ## make sure path exits - autocreate dirs
141
+ ## make sure path exists
142
+ dirname = File.dirname( "#{dest}.#{format}" )
143
+ FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname )
144
+
145
+ if format == 'svg'
146
+ ## save as text (note: assume utf-8 encoding for now)
147
+ text = response.body.to_s
148
+ text = text.force_encoding( Encoding::UTF_8 )
149
+
150
+ File.open( "#{dest}.svg", 'w:utf-8' ) do |f|
151
+ f.write( text )
152
+ end
153
+ else
154
+ ## save as binary
155
+ File.open( "#{dest}.#{format}", 'wb' ) do |f|
156
+ f.write( response.body )
157
+ end
158
+ end
159
+ else
160
+ puts "!! error:"
161
+ puts "#{response.code} #{response.message}"
162
+ exit 1
163
+ end
164
+ end
165
+
166
+
167
+
168
+
@@ -0,0 +1,31 @@
1
+ module Pixelart
2
+
3
+ class Image
4
+
5
+ ###
6
+ # add common
7
+ # pixel(ate) steps/offsets (for re/down/sampling)
8
+ DOwNSAMPLING_STEPS = {
9
+ '24x24' => {
10
+ '269x269' => Image.calc_sample_steps( 269, 24 ), # width (269px), new_width (24px)
11
+ '512x512' => Image.calc_sample_steps( 512, 24 ), # width (512px), new_width (24px)
12
+ },
13
+ '32x32' => {
14
+ '320x320' => Image.calc_sample_steps( 320, 32 ),
15
+ '512x512' => Image.calc_sample_steps( 512, 32 ),
16
+ },
17
+ '35x35' => {
18
+ '512x512' => Image.calc_sample_steps( 512, 35 ),
19
+ },
20
+ '60x60' => {
21
+ '512x512' => Image.calc_sample_steps( 512, 60 ),
22
+ },
23
+ '80x80' => {
24
+ '512x512' => Image.calc_sample_steps( 512, 80 ),
25
+ },
26
+ }
27
+
28
+ end # class Image
29
+ end # module Pixelart
30
+
31
+
data/lib/artbase/image.rb CHANGED
@@ -1,75 +1,31 @@
1
- ######################
2
- # pixelart image extensions
3
- # move upstream!!!!!
4
-
5
-
6
- module Pixelart
7
-
8
- class Image
9
- def sample( *args, **kwargs )
10
- ## note: for now always assume square image (e.g. 24x24, 32x32 and such)
11
-
12
- offsets = if kwargs[:from] && kwargs[:to]
13
- PIXEL_OFFSETS[ kwargs[:to] ][ kwargs[ :from ]]
14
- else
15
- args[0] ## assume "custom" hash of offsets
16
- end
17
-
18
- width = height = offsets.size
19
-
20
- puts " #{self.width}x#{self.height} => #{width}x#{height}"
21
-
22
-
23
- dest = Image.new( width, height )
24
-
25
- offsets.each do |offset_x, x|
26
- offsets.each do |offset_y, y|
27
- pixel = self[offset_x,offset_y]
28
-
29
- dest[x,y] = pixel
30
- end
31
- end
32
-
33
- dest
34
- end
35
- alias_method :pixelate, :sample
36
- end # class Image
37
-
38
-
39
-
40
- class ImageComposite
41
- def add_glob( glob )
42
- files = Dir.glob( glob )
43
- puts "#{files.size} file(s) found matching >#{glob}<"
44
-
45
-
46
- files = files.sort
47
- ## puts files.inspect
48
-
49
- files.each_with_index do |file,i|
50
- puts "==> [#{i+1}/#{files.size}] - #{file}"
51
- img = Image.read( file )
52
-
53
- self << img ## todo/check: use add alias - why? why not?
54
- end
55
- end
56
- end # class ImageComposite
57
- end # module Pixelart
58
-
59
-
60
- ###
61
- # add common
62
- # pixel(ate) offsets (for sampling)
63
- PIXEL_OFFSETS = {}
64
-
65
- module Pixelart
66
- class Image
67
- PIXEL_OFFSETS = ::PIXEL_OFFSETS
68
- end
69
- end # module Pixelart
70
-
71
-
72
- require_relative 'image/24x24'
73
- require_relative 'image/32x32'
74
- require_relative 'image/60x60'
75
- require_relative 'image/80x80'
1
+ ######################
2
+ # pixelart image extensions
3
+ # move upstream!!!!!
4
+
5
+
6
+ module Pixelart
7
+ class ImageComposite
8
+ def add_glob( glob )
9
+ files = Dir.glob( glob )
10
+ puts "#{files.size} file(s) found matching >#{glob}<"
11
+
12
+
13
+ files = files.sort
14
+ ## puts files.inspect
15
+
16
+ files.each_with_index do |file,i|
17
+ puts "==> [#{i+1}/#{files.size}] - #{file}"
18
+ img = Image.read( file )
19
+
20
+ self << img ## todo/check: use add alias - why? why not?
21
+ end
22
+ end
23
+ end # class ImageComposite
24
+ end # module Pixelart
25
+
26
+
27
+
28
+ require_relative 'image/sample' ## check - change to downsample/pixelate - why? why not?
29
+
30
+
31
+
@@ -0,0 +1,41 @@
1
+
2
+ ## for more ideas on retry
3
+ ## see https://github.com/ooyala/retries
4
+
5
+
6
+ ## todo/check: use a different name than retry - why? why not?
7
+ def retry_on_error( max_tries: 3, &block )
8
+ errors = []
9
+ delay = 3 ## 3 secs
10
+
11
+ begin
12
+ block.call
13
+
14
+ ## note: add more exception here (separated by comma) like
15
+ ## rescue Errno::ETIMEDOUT, Errno::ECONNREFUSED => e
16
+ rescue Net::ReadTimeout => e
17
+ ## (re)raise (use raise with arguments or such - why? why not?)
18
+ raise if errors.size >= max_tries
19
+
20
+ ## ReadTimeout, a subclass of Timeout::Error, is raised if a chunk of the response cannot be read within the read_timeout.
21
+ ## subclass of RuntimeError
22
+ ## subclass of StandardError
23
+ ## subclass of Exception
24
+ puts "!! ERROR - #{e}:"
25
+ pp e
26
+
27
+ errors << e
28
+
29
+ puts
30
+ puts "==> retrying (count=#{errors.size}, max_tries=#{max_tries}) in #{delay} sec(s)..."
31
+ sleep( delay )
32
+ retry
33
+ end
34
+
35
+ if errors.size > 0
36
+ puts " #{errors.size} retry attempt(s) on error(s):"
37
+ pp errors
38
+ end
39
+
40
+ errors
41
+ end