profilepic 0.1.0 → 0.1.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: 9f6333d662946773d2af33fa3d776bafe894e7bf91086d2258ab10b2395d91d6
4
- data.tar.gz: 73bcbdc5a25884aafc8f2cdbc85b4658b09e0c371cd2c8ff1d4b6664ea0da3ae
3
+ metadata.gz: 1ba2adc7eb706d797e6295d1aa4a2a66a84cb48e70e82355cdd60e519436fe78
4
+ data.tar.gz: 0efd5f64c0506376f1a61af437dc2085a771a057719d9a59e1894d6c74a50604
5
5
  SHA512:
6
- metadata.gz: 0236e6a9e43d77384c1beb48dcd0e2e107c110026e56ef8fa45862c4d035451afd07a6194c4d9efebb69a5995be6026998d8d51f521183c893cd95777a7bf806
7
- data.tar.gz: 4324b06b0fffaab639a3e5a580b21ecd40ee9067c99b097536a912a6e7350baf3b5a6b2478c5a0a50b9a998a5200024ec7f7f8af82d459cc73618d0497a04744
6
+ metadata.gz: 0bf5c048b1ff9cf265b67c1b4d1b390f15dc46bc4d43b300ae52a7487b97836c849b1bacf0dbc107ba78284d8479e303216ff9f32e316ee1a2e0c6c37bfe7b79
7
+ data.tar.gz: 6d6692873afe1b608c354bfc23124be010ec209d90beacfa6bade0bb119ae11400fe4af4a885bdccc516b7173b9891322b5cea9631a7f82c280e6952bc6c9e86
data/Manifest.txt CHANGED
@@ -4,9 +4,12 @@ README.md
4
4
  Rakefile
5
5
  bin/profilepic
6
6
  lib/profilepic.rb
7
+ lib/profilepic/builder.rb
7
8
  lib/profilepic/public/style.css
8
9
  lib/profilepic/service.rb
9
10
  lib/profilepic/version.rb
10
11
  lib/profilepic/views/index.erb
11
12
  lib/profilepic/views/layout.erb
13
+ lib/profilepic/views/marcs.erb
14
+ lib/profilepic/views/shared/_more_options.erb
12
15
  lib/profilepic/views/shared/_version.erb
@@ -0,0 +1,105 @@
1
+
2
+ ## keep cache of generated images (profile pics)
3
+ IMAGES = {}
4
+
5
+
6
+
7
+
8
+ class ImageReq ## (Generate) Image Request
9
+ def self.build( params )
10
+ puts "==> image request params:"
11
+ pp params
12
+
13
+ name = _norm_key( params[:t] || 'punk' )
14
+ attributes = _parse_attributes( params[:attributes] || '' )
15
+
16
+ zoom = _parse_zoom( params[:z] || '1' )
17
+ background = _norm_key( params[:bg] || 'none' )
18
+
19
+ new( name: name,
20
+ attributes: attributes,
21
+ zoom: zoom,
22
+ background: background )
23
+ end
24
+
25
+ def self.build_marc( params )
26
+ puts "==> image request params:"
27
+ pp params
28
+
29
+ name = 'marc'
30
+ archetype = _norm_key( params[:t] || 'marc' )
31
+ more_attributes = _parse_attributes( params[:attributes] || '' )
32
+
33
+ eyes = _norm_key( params[:eyes] || 'none' )
34
+ face = _norm_key( params[:face] || 'none' )
35
+ beard = _norm_key( params[:beard] || 'none' )
36
+ hair = _norm_key( params[:hair] || 'none' )
37
+ headwear = _norm_key( params[:headwear] || 'none' )
38
+ eyewear = _norm_key( params[:eyewear] || 'none' )
39
+ mouth = _norm_key( params[:mouth] || 'none' )
40
+
41
+ zoom = _parse_zoom( params[:z] || '1' )
42
+ background = _norm_key( params[:bg] || 'none' )
43
+
44
+ attributes = [archetype]
45
+ attributes << eyes if eyes != 'none'
46
+ attributes << face if face != 'none'
47
+ attributes << hair if hair != 'none'
48
+ attributes << beard if beard != 'none'
49
+ attributes << headwear if headwear != 'none'
50
+ attributes << eyewear if eyewear != 'none'
51
+ attributes << mouth if mouth != 'none'
52
+
53
+ new( name: name,
54
+ attributes: attributes + more_attributes,
55
+ zoom: zoom,
56
+ background: background )
57
+ end
58
+
59
+
60
+ def self._norm_key( str )
61
+ str.downcase.strip
62
+ end
63
+
64
+ def self._parse_attributes( str )
65
+ # convert attributes to array
66
+ ## allow various separators
67
+ attributes = str.split( %r{[,;|+/]+} )
68
+ attributes = attributes.map { |attr| attr.strip }
69
+ attributes = attributes.select { |attr| !attr.empty?} ## remove empty strings (if any)
70
+ attributes
71
+ end
72
+
73
+ def self._parse_zoom( str )
74
+ str.strip.to_i( 10 )
75
+ end
76
+
77
+
78
+ attr_reader :name,
79
+ :attributes,
80
+ :zoom,
81
+ :background
82
+ def initialize( name:, attributes:, zoom:, background: )
83
+ @name = name
84
+ @attributes = attributes
85
+ @zoom = zoom
86
+ @background = background
87
+ end
88
+
89
+ def image
90
+ img = Original::Image.fabricate( @name, *@attributes )
91
+ img = img.background( @background ) if @background != 'none'
92
+ img = img.zoom( @zoom ) if [2,3,4,5,6,7,8,9,10,20].include?( @zoom )
93
+ img
94
+ end
95
+
96
+ def image_key
97
+ @key ||= begin
98
+ key = "#{@name}#{Time.now.to_i}"
99
+ key << "@#{@zoom}x" if [2,3,4,5,6,7,8,9,10,20].include?( @zoom )
100
+ key
101
+ end
102
+ @key
103
+ end
104
+ end
105
+
@@ -5,12 +5,12 @@ body {
5
5
 
6
6
  a, a:visited {
7
7
  text-decoration: none;
8
- color: maroon;
8
+ /* color: maroon; */
9
9
  }
10
10
 
11
11
  a:hover {
12
12
  text-decoration: underline;
13
- color: maroon;
13
+ /* color: maroon; */
14
14
  }
15
15
 
16
16
 
@@ -1,57 +1,229 @@
1
+
2
+ ###
3
+ # helpers
4
+ # to generate
5
+
6
+ def radio_options( options,
7
+ name:,
8
+ legend: )
9
+
10
+ buf = <<TXT
11
+ <fieldset>
12
+ <legend>#{legend}:</legend>
13
+ TXT
14
+
15
+ options.each_with_index do |option,i|
16
+
17
+ value = option.downcase
18
+ label = option
19
+
20
+ buf += <<TXT
21
+ <div>
22
+ <input type="radio" id="#{name}#{i}" name="#{name}" value="#{value}"
23
+ #{ i==0 ? 'checked' : '' }
24
+ <label for="#{name}#{i}">#{label}</label>
25
+ </div>
26
+ TXT
27
+ end
28
+
29
+ buf += "</fieldset>\n"
30
+ buf
31
+ end
32
+
33
+
34
+
35
+ MARC_ARCHETYPE = [
36
+ 'Marc',
37
+ 'Marc Mid',
38
+ 'Marc Dark',
39
+ 'Marc Albino',
40
+ 'Marc Golden',
41
+ 'Mad Lad',
42
+ 'Zombie',
43
+ 'Ape',
44
+ 'Ape Golden',
45
+ 'Ape Pink',
46
+ 'Alien',
47
+ 'Alien Green',
48
+ 'Devil',
49
+ 'Orc',
50
+ 'Skeleton',
51
+ 'Bot']
52
+
53
+
54
+ MARC_EYES = [
55
+ 'Blue Eyes',
56
+ 'Green Eyes',
57
+ ]
58
+
59
+ MARC_FACE = [
60
+ 'Blue Eye Shadow',
61
+ 'Green Eye Shadow',
62
+ 'Purple Eye Shadow',
63
+ 'Clown Eyes Blue',
64
+ 'Clown Eyes Green',
65
+ 'Bagner',
66
+ 'Marc Tyson',
67
+ 'Tears',
68
+ ]
69
+
70
+ MARC_BEARD = [
71
+ 'Big Beard White',
72
+ 'Big Beard',
73
+ 'Chinstrap',
74
+ 'Front Beard',
75
+ 'Front Beard Dark',
76
+ 'Full Mustache',
77
+ 'Full Mustache Dark',
78
+ 'Goat',
79
+ 'Goat Dark',
80
+ 'Handlebar',
81
+ 'Luxurious Beard',
82
+ 'Mustache',
83
+ 'Mutton Chop',
84
+ 'Normal Beard',
85
+ 'Normal Beard Black',
86
+ 'Shadow Beard',
87
+ 'Soul Patch',
88
+ ]
89
+
90
+ MARC_HAIR = [
91
+ 'Blonde Bob',
92
+ 'Chad',
93
+ 'Clown Hair',
94
+ 'Crazy White Hair',
95
+ 'Crazy Hair',
96
+ 'Frumpy Hair',
97
+ 'Marc Three',
98
+ 'Purple Hair',
99
+ 'Stringy Hair',
100
+ 'Vampire Hair',
101
+ 'Wild Blonde Hair',
102
+ 'Wild Hair',
103
+ ]
104
+
105
+ MARC_HEADWEAR = [
106
+ 'Bandana',
107
+ 'Beanie',
108
+ 'Bunny Ears',
109
+ 'Cap',
110
+ 'Skull Cap',
111
+ 'Cap Forward',
112
+ 'Police Cap',
113
+ 'Cowboy Hat',
114
+ 'Do Rag',
115
+ 'Fast Food',
116
+ 'Marcdonalds',
117
+ 'Fedora',
118
+ 'Headband',
119
+ 'Roaring Headband',
120
+ 'Hoodie',
121
+ 'Purple Hoodie',
122
+ 'Knitted Cap',
123
+ 'Laurels',
124
+ 'Shemagh',
125
+ 'Tassle Hat',
126
+ 'Tiarra',
127
+ 'Top Hat',
128
+ 'Uncle Sam',
129
+ 'Viking',
130
+ 'Welding Goggles',
131
+ ]
132
+
133
+
134
+ MARC_EYEWEAR = [
135
+ '3D Glasses',
136
+ 'Aviators',
137
+ 'Big Shades',
138
+ 'Classic Shades',
139
+ 'Deal With It',
140
+ 'Glasses',
141
+ 'Gold Glasses',
142
+ 'Horned-Rim Glasses',
143
+ 'Monocle',
144
+ 'Nerd Glasses',
145
+ 'Pink Shades',
146
+ 'Polarized',
147
+ 'Polarized White',
148
+ 'Regular Shades',
149
+ 'Small Shades',
150
+ 'VR Headset',
151
+ 'Eye Mask',
152
+ 'Eye Patch',
153
+ 'Lasers']
154
+
155
+ MARC_MOUTH_PROP = [
156
+ 'Cigar',
157
+ 'Cigarette',
158
+ 'Hookah',
159
+ 'Pipe',
160
+ 'Vape',
161
+ 'Medical Mask',
162
+ 'Bubble Gum' ]
163
+
164
+
165
+
166
+
1
167
  class ProfilepicService < Sinatra::Base
2
168
 
169
+ get '/cache' do
170
+
171
+ html =<<HTML
172
+ <pre>
173
+ #{IMAGES.size} image(s) in cache:
174
+
175
+
176
+ </pre>
177
+ HTML
178
+ html
179
+ end
180
+
181
+
182
+
3
183
  get '/' do
4
184
  erb :index
5
185
  end
6
186
 
187
+ get '/marcs' do
188
+ erb :marcs
189
+ end
7
190
 
8
- get '/generate' do
9
- type = params[:t] || "punk"
10
- attributes = params[:attributes] || ""
11
- zoom = params[:z] || "1"
12
- background = params[:bg] || "none"
13
-
14
- txt= <<TXT
15
- image generation (string) params:
16
- type: >#{type}< - #{type.class.name}
17
- attributes: >#{attributes}< - #{attributes.class.name}
18
- zoom: >#{zoom}< - #{zoom.class.name}
19
- background >#{background}< - #{background.class.name}
20
- TXT
21
191
 
22
- # convert attributes to array
23
- ## allow various separators
24
- attributes = attributes.split( %r{[,;|+/]+} )
25
- attributes = attributes.map { |attr| attr.strip }
26
- attributes = attributes.select { |attr| !attr.empty?} ## remove empty strings (if any)
27
-
28
- type = type.downcase.strip
29
- zoom = zoom.strip.to_i( 10 )
30
- background = background.downcase.strip
31
-
32
- txt += <<TXT
33
- resulting in:
34
- type: >#{type}< - #{type.class.name}
35
- #{attributes.size} attribute(s):
36
- #{attributes.join(', ')}
37
- zoom @ #{zoom}x - #{zoom.class.name}
38
- background >#{background}< - #{background.class.name}
39
- TXT
192
+ get '/generate_marcs' do
193
+
194
+ r = ImageReq.build_marc( params )
40
195
 
41
- puts "generate request:"
42
- puts txt
196
+ img = r.image
43
197
 
44
- img = Original::Image.fabricate( type, *attributes )
45
- img = img.background( background ) if background != 'none'
46
- img = img.zoom( zoom ) if [2,3,4,5,6,7,8,9,10,20].include?( zoom )
198
+ blob = img.image.to_blob
199
+ IMAGES[ r.image_key ] = blob
200
+ redirect "/#{r.image_key}.png"
201
+ end
202
+
203
+
204
+ get '/generate' do
47
205
 
48
- # check - add a debug/save option - why? why not?
49
- # img.save( "./tmp/profilepic-#{Time.now.to_i}.png" )
206
+ r = ImageReq.build( params )
50
207
 
51
- headers( 'Content-Type' => "image/png" )
208
+ img = r.image
52
209
 
53
210
  blob = img.image.to_blob
54
- blob
211
+ IMAGES[ r.image_key ] = blob
212
+ redirect "/#{r.image_key}.png"
213
+ end
214
+
215
+
216
+ get '/:key.png' do
217
+ puts " .png image request for key: >#{params[:key]}<"
218
+
219
+ blob = IMAGES[ params[:key] ]
220
+
221
+ if blob
222
+ headers( 'Content-Type' => "image/png" )
223
+ blob
224
+ else
225
+ "404 not found; sorry no generated .png image found for key >#{params[:key]}<"
226
+ end
55
227
  end
56
228
  end
57
229
 
@@ -3,7 +3,7 @@
3
3
  module Profilepic
4
4
  MAJOR = 0
5
5
  MINOR = 1
6
- PATCH = 0
6
+ PATCH = 1
7
7
  VERSION = [MAJOR,MINOR,PATCH].join('.')
8
8
 
9
9
  def self.version
@@ -33,6 +33,7 @@ own 100% forever.
33
33
  <div>
34
34
  <input type="radio" id="t4" name="t" value="marc">
35
35
  <label for="t4">Marc (24×24)</label>
36
+ ... or try the <b><a href="/marcs">Design Your Own Marc Wizard »</a></b>
36
37
  </div>
37
38
 
38
39
  <div>
@@ -74,53 +75,6 @@ own 100% forever.
74
75
  </div>
75
76
 
76
77
 
77
- <p>More options:</p>
78
-
79
- <fieldset>
80
- <legend>Select a zoom size:</legend>
81
-
82
- <div>
83
- <input type="radio" id="z1" name="z" value="1"
84
- checked>
85
- <label for="z1">1X</label>
86
- </div>
87
-
88
- <div>
89
- <input type="radio" id="z2" name="z" value="2">
90
- <label for="z2">2X</label>
91
- </div>
92
-
93
- <div>
94
- <input type="radio" id="z4" name="z" value="4">
95
- <label for="z4">4X</label>
96
- </div>
97
-
98
- <div>
99
- <input type="radio" id="z8" name="z" value="8">
100
- <label for="z8">8X</label>
101
- </div>
102
- </fieldset>
103
-
104
-
105
- <fieldset>
106
- <legend>Select a background:</legend>
107
-
108
- <div>
109
- <input type="radio" id="bg1" name="bg" value="none"
110
- checked>
111
- <label for="bg1">None (Transparent)</label>
112
- </div>
113
-
114
- <div>
115
- <input type="radio" id="bg2" name="bg" value="ukraine">
116
- <label for="bg2">We Stand With Ukraine</label>
117
- </div>
118
-
119
- <div>
120
- <input type="radio" id="bg3" name="bg" value="rainbow">
121
- <label for="bg3">Pride / Rainbow</label>
122
- </div>
123
- </fieldset>
124
-
78
+ <%= erb :'shared/_more_options' %>
125
79
 
126
80
  </form>
@@ -0,0 +1,84 @@
1
+
2
+ <h1>Marcs (24×24) - Profile Pic(ture) As Service</h1>
3
+
4
+ <p>Yes, you can!
5
+ Generate your own originals that you
6
+ own 100% forever.
7
+ </p>
8
+
9
+
10
+
11
+ <form action="/generate_marcs" method="get" id="form1">
12
+
13
+
14
+ <%= radio_options( MARC_ARCHETYPE,
15
+ name: 't',
16
+ legend: 'Select a marc base (archetype)' ) %>
17
+
18
+ Options:
19
+
20
+
21
+ <%= radio_options( ['None']+MARC_EYES,
22
+ name: 'eyes',
23
+ legend: 'Select eyes (extras)' ) %>
24
+
25
+ <%= radio_options( ['None']+MARC_FACE,
26
+ name: 'face',
27
+ legend: 'Select face (extras)' ) %>
28
+
29
+ <%= radio_options( ['None']+MARC_BEARD,
30
+ name: 'beard',
31
+ legend: 'Select beard' ) %>
32
+
33
+ <%= radio_options( ['None']+MARC_HAIR,
34
+ name: 'hair',
35
+ legend: 'Select hair' ) %>
36
+
37
+ <%= radio_options( ['None']+MARC_HEADWEAR,
38
+ name: 'headwear',
39
+ legend: 'Select headwear' ) %>
40
+
41
+
42
+ <%= radio_options( ['None']+MARC_EYEWEAR,
43
+ name: 'eyewear',
44
+ legend: 'Select eyewear' ) %>
45
+
46
+ <%= radio_options( ['None']+MARC_MOUTH_PROP,
47
+ name: 'mouth',
48
+ legend: 'Select mouth prop' ) %>
49
+
50
+
51
+ <div>
52
+ <button type="submit" form="form1" value="Submit"
53
+ style="font-size: 400%; color: white; background-color: blue;">Generate Profile Pic(ture) in .PNG Format</button>
54
+ </div>
55
+
56
+
57
+
58
+ Or
59
+
60
+ <fieldset>
61
+ <legend>Type (more) attribute description / specification:</legend>
62
+
63
+ <div>
64
+ <input type="text" id="attributes" name="attributes"
65
+ minlength="0" maxlength="200" size="80"
66
+ style="font-size: 200%;"
67
+ placeholder="Attribute 1, Attribute 2, Attribute 3, ...">
68
+
69
+ <p>
70
+ Examples:
71
+ </p>
72
+ <ul>
73
+ <li>Normal Beard, Big Shades</li>
74
+ <li>Crazy Hair, 3D Glasses</li>
75
+ <li>Headband</li>
76
+ </ul>
77
+
78
+ </div>
79
+ </fieldset>
80
+
81
+
82
+ <%= erb :'shared/_more_options' %>
83
+
84
+ </form>
@@ -0,0 +1,49 @@
1
+
2
+ <p>More options:</p>
3
+
4
+ <fieldset>
5
+ <legend>Select a zoom size:</legend>
6
+
7
+ <div>
8
+ <input type="radio" id="z1" name="z" value="1"
9
+ checked>
10
+ <label for="z1">1X</label>
11
+ </div>
12
+
13
+ <div>
14
+ <input type="radio" id="z2" name="z" value="2">
15
+ <label for="z2">2X</label>
16
+ </div>
17
+
18
+ <div>
19
+ <input type="radio" id="z4" name="z" value="4">
20
+ <label for="z4">4X</label>
21
+ </div>
22
+
23
+ <div>
24
+ <input type="radio" id="z8" name="z" value="8">
25
+ <label for="z8">8X</label>
26
+ </div>
27
+ </fieldset>
28
+
29
+
30
+ <fieldset>
31
+ <legend>Select a background:</legend>
32
+
33
+ <div>
34
+ <input type="radio" id="bg1" name="bg" value="none"
35
+ checked>
36
+ <label for="bg1">None (Transparent)</label>
37
+ </div>
38
+
39
+ <div>
40
+ <input type="radio" id="bg2" name="bg" value="ukraine">
41
+ <label for="bg2">We Stand With Ukraine</label>
42
+ </div>
43
+
44
+ <div>
45
+ <input type="radio" id="bg3" name="bg" value="rainbow">
46
+ <label for="bg3">Pride / Rainbow</label>
47
+ </div>
48
+ </fieldset>
49
+
data/lib/profilepic.rb CHANGED
@@ -8,6 +8,7 @@ require 'webrick'
8
8
 
9
9
  ## our own code
10
10
  require 'profilepic/version' # note: let version always go first
11
+ require 'profilepic/builder'
11
12
  require 'profilepic/service'
12
13
 
13
14
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: profilepic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.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: 2022-08-04 00:00:00.000000000 Z
11
+ date: 2022-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: originals
@@ -102,11 +102,14 @@ files:
102
102
  - Rakefile
103
103
  - bin/profilepic
104
104
  - lib/profilepic.rb
105
+ - lib/profilepic/builder.rb
105
106
  - lib/profilepic/public/style.css
106
107
  - lib/profilepic/service.rb
107
108
  - lib/profilepic/version.rb
108
109
  - lib/profilepic/views/index.erb
109
110
  - lib/profilepic/views/layout.erb
111
+ - lib/profilepic/views/marcs.erb
112
+ - lib/profilepic/views/shared/_more_options.erb
110
113
  - lib/profilepic/views/shared/_version.erb
111
114
  homepage: https://github.com/profilepic/profilepic
112
115
  licenses: