nameplate 0.1.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.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +122 -0
- data/Rakefile +39 -0
- data/lib/nameplate/avatar/cache.rb +59 -0
- data/lib/nameplate/avatar/generator.rb +237 -0
- data/lib/nameplate/avatar/identity.rb +41 -0
- data/lib/nameplate/avatar.rb +37 -0
- data/lib/nameplate/colors/palette.rb +45 -0
- data/lib/nameplate/colors/palettes/custom.rb +20 -0
- data/lib/nameplate/colors/palettes/dracula.rb +29 -0
- data/lib/nameplate/colors/palettes/google.rb +55 -0
- data/lib/nameplate/colors/palettes/iwanthue.rb +234 -0
- data/lib/nameplate/colors/palettes/jedi_light.rb +26 -0
- data/lib/nameplate/colors/palettes/monokai.rb +27 -0
- data/lib/nameplate/colors/palettes/pastel.rb +24 -0
- data/lib/nameplate/colors.rb +42 -0
- data/lib/nameplate/configuration.rb +109 -0
- data/lib/nameplate/fonts/Lato-Light.ttf +0 -0
- data/lib/nameplate/fonts/Roboto-Medium +0 -0
- data/lib/nameplate/has_avatar.rb +33 -0
- data/lib/nameplate/image/resize.rb +111 -0
- data/lib/nameplate/results/failure_result.rb +35 -0
- data/lib/nameplate/results/success_result.rb +27 -0
- data/lib/nameplate/utils/path_helper.rb +18 -0
- data/lib/nameplate/version.rb +5 -0
- data/lib/nameplate/view_helpers/avatar_helper.rb +60 -0
- data/lib/nameplate.rb +57 -0
- data/spec/fixtures/in.png +0 -0
- data/spec/nameplate/avatar/cache_spec.rb +35 -0
- data/spec/nameplate/avatar/generator_spec.rb +108 -0
- data/spec/nameplate/avatar/identity_spec.rb +27 -0
- data/spec/nameplate/colors_spec.rb +34 -0
- data/spec/nameplate/image/resize_spec.rb +96 -0
- data/spec/nameplate/utils/path_helper_spec.rb +16 -0
- data/spec/nameplate/view_helpers/avatar_helper_spec.rb +38 -0
- data/spec/nameplate_spec.rb +102 -0
- data/spec/spec_helper.rb +13 -0
- metadata +111 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NamePlate
|
|
4
|
+
module Colors
|
|
5
|
+
module Palettes
|
|
6
|
+
class Google < Palette
|
|
7
|
+
GOOGLE_COLORS = [
|
|
8
|
+
[226, 95, 81], # A
|
|
9
|
+
[242, 96, 145], # B
|
|
10
|
+
[187, 101, 202], # C
|
|
11
|
+
[149, 114, 207], # D
|
|
12
|
+
[120, 132, 205], # E
|
|
13
|
+
[91, 149, 249], # F
|
|
14
|
+
[72, 194, 249], # G
|
|
15
|
+
[69, 208, 226], # H
|
|
16
|
+
[72, 182, 172], # I
|
|
17
|
+
[82, 188, 137], # J
|
|
18
|
+
[155, 206, 95], # K
|
|
19
|
+
[212, 227, 74], # L
|
|
20
|
+
[254, 218, 16], # M
|
|
21
|
+
[247, 192, 0], # N
|
|
22
|
+
[255, 168, 0], # O
|
|
23
|
+
[255, 138, 96], # P
|
|
24
|
+
[194, 194, 194], # Q
|
|
25
|
+
[143, 164, 175], # R
|
|
26
|
+
[162, 136, 126], # S
|
|
27
|
+
[163, 163, 163], # T
|
|
28
|
+
[175, 181, 226], # U
|
|
29
|
+
[179, 155, 221], # V
|
|
30
|
+
[194, 194, 194], # W
|
|
31
|
+
[124, 222, 235], # X
|
|
32
|
+
[188, 170, 164], # Y
|
|
33
|
+
[173, 214, 125] # Z
|
|
34
|
+
].freeze
|
|
35
|
+
|
|
36
|
+
def self.key = :google
|
|
37
|
+
|
|
38
|
+
def initialize
|
|
39
|
+
super(GOOGLE_COLORS)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def pick(username)
|
|
43
|
+
char = username[0].upcase
|
|
44
|
+
if /[A-Z]/.match?(char)
|
|
45
|
+
colors[char.ord - 65]
|
|
46
|
+
elsif /[0-9]/.match?(char)
|
|
47
|
+
colors[char.to_i]
|
|
48
|
+
else
|
|
49
|
+
super
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NamePlate
|
|
4
|
+
module Colors
|
|
5
|
+
module Palettes
|
|
6
|
+
class Iwanthue < Palette
|
|
7
|
+
IWANTHUE_COLORS = [
|
|
8
|
+
[198, 125, 40],
|
|
9
|
+
[61, 155, 243],
|
|
10
|
+
[74, 243, 75],
|
|
11
|
+
[238, 89, 166],
|
|
12
|
+
[52, 240, 224],
|
|
13
|
+
[177, 156, 155],
|
|
14
|
+
[240, 120, 145],
|
|
15
|
+
[111, 154, 78],
|
|
16
|
+
[237, 179, 245],
|
|
17
|
+
[237, 101, 95],
|
|
18
|
+
[89, 239, 155],
|
|
19
|
+
[43, 254, 70],
|
|
20
|
+
[163, 212, 245],
|
|
21
|
+
[65, 152, 142],
|
|
22
|
+
[165, 135, 246],
|
|
23
|
+
[181, 166, 38],
|
|
24
|
+
[187, 229, 206],
|
|
25
|
+
[77, 164, 25],
|
|
26
|
+
[179, 246, 101],
|
|
27
|
+
[234, 93, 37],
|
|
28
|
+
[225, 155, 115],
|
|
29
|
+
[142, 140, 188],
|
|
30
|
+
[223, 120, 140],
|
|
31
|
+
[249, 174, 27],
|
|
32
|
+
[244, 117, 225],
|
|
33
|
+
[137, 141, 102],
|
|
34
|
+
[75, 191, 146],
|
|
35
|
+
[188, 239, 142],
|
|
36
|
+
[164, 199, 145],
|
|
37
|
+
[173, 120, 149],
|
|
38
|
+
[59, 195, 89],
|
|
39
|
+
[222, 198, 220],
|
|
40
|
+
[68, 145, 187],
|
|
41
|
+
[236, 204, 179],
|
|
42
|
+
[159, 195, 72],
|
|
43
|
+
[188, 121, 189],
|
|
44
|
+
[166, 160, 85],
|
|
45
|
+
[181, 233, 37],
|
|
46
|
+
[236, 177, 85],
|
|
47
|
+
[121, 147, 160],
|
|
48
|
+
[234, 218, 110],
|
|
49
|
+
[241, 157, 191],
|
|
50
|
+
[62, 200, 234],
|
|
51
|
+
[133, 243, 34],
|
|
52
|
+
[88, 149, 110],
|
|
53
|
+
[59, 228, 248],
|
|
54
|
+
[183, 119, 118],
|
|
55
|
+
[251, 195, 45],
|
|
56
|
+
[113, 196, 122],
|
|
57
|
+
[197, 115, 70],
|
|
58
|
+
[80, 175, 187],
|
|
59
|
+
[103, 231, 238],
|
|
60
|
+
[240, 72, 133],
|
|
61
|
+
[228, 149, 241],
|
|
62
|
+
[180, 188, 159],
|
|
63
|
+
[172, 132, 85],
|
|
64
|
+
[180, 135, 251],
|
|
65
|
+
[236, 194, 58],
|
|
66
|
+
[217, 176, 109],
|
|
67
|
+
[88, 244, 199],
|
|
68
|
+
[186, 157, 239],
|
|
69
|
+
[113, 230, 96],
|
|
70
|
+
[206, 115, 165],
|
|
71
|
+
[244, 178, 163],
|
|
72
|
+
[230, 139, 26],
|
|
73
|
+
[241, 125, 89],
|
|
74
|
+
[83, 160, 66],
|
|
75
|
+
[107, 190, 166],
|
|
76
|
+
[197, 161, 210],
|
|
77
|
+
[198, 203, 245],
|
|
78
|
+
[238, 117, 19],
|
|
79
|
+
[228, 119, 116],
|
|
80
|
+
[131, 156, 41],
|
|
81
|
+
[145, 178, 168],
|
|
82
|
+
[139, 170, 220],
|
|
83
|
+
[233, 95, 125],
|
|
84
|
+
[87, 178, 230],
|
|
85
|
+
[157, 200, 119],
|
|
86
|
+
[237, 140, 76],
|
|
87
|
+
[229, 185, 186],
|
|
88
|
+
[144, 206, 212],
|
|
89
|
+
[236, 209, 158],
|
|
90
|
+
[185, 189, 79],
|
|
91
|
+
[34, 208, 66],
|
|
92
|
+
[84, 238, 129],
|
|
93
|
+
[133, 140, 134],
|
|
94
|
+
[67, 157, 94],
|
|
95
|
+
[168, 179, 25],
|
|
96
|
+
[140, 145, 240],
|
|
97
|
+
[151, 241, 125],
|
|
98
|
+
[67, 162, 107],
|
|
99
|
+
[200, 156, 21],
|
|
100
|
+
[169, 173, 189],
|
|
101
|
+
[226, 116, 189],
|
|
102
|
+
[133, 231, 191],
|
|
103
|
+
[194, 161, 63],
|
|
104
|
+
[241, 77, 99],
|
|
105
|
+
[241, 217, 53],
|
|
106
|
+
[123, 204, 105],
|
|
107
|
+
[210, 201, 119],
|
|
108
|
+
[229, 108, 155],
|
|
109
|
+
[240, 91, 72],
|
|
110
|
+
[187, 115, 210],
|
|
111
|
+
[240, 163, 100],
|
|
112
|
+
[178, 217, 57],
|
|
113
|
+
[179, 135, 116],
|
|
114
|
+
[204, 211, 24],
|
|
115
|
+
[186, 135, 57],
|
|
116
|
+
[223, 176, 135],
|
|
117
|
+
[204, 148, 151],
|
|
118
|
+
[116, 223, 50],
|
|
119
|
+
[95, 195, 46],
|
|
120
|
+
[123, 160, 236],
|
|
121
|
+
[181, 172, 131],
|
|
122
|
+
[142, 220, 202],
|
|
123
|
+
[240, 140, 112],
|
|
124
|
+
[172, 145, 164],
|
|
125
|
+
[228, 124, 45],
|
|
126
|
+
[135, 151, 243],
|
|
127
|
+
[42, 205, 125],
|
|
128
|
+
[192, 233, 116],
|
|
129
|
+
[119, 170, 114],
|
|
130
|
+
[158, 138, 26],
|
|
131
|
+
[73, 190, 183],
|
|
132
|
+
[185, 229, 243],
|
|
133
|
+
[227, 107, 55],
|
|
134
|
+
[196, 205, 202],
|
|
135
|
+
[132, 143, 60],
|
|
136
|
+
[233, 192, 237],
|
|
137
|
+
[62, 150, 220],
|
|
138
|
+
[205, 201, 141],
|
|
139
|
+
[106, 140, 190],
|
|
140
|
+
[161, 131, 205],
|
|
141
|
+
[135, 134, 158],
|
|
142
|
+
[198, 139, 81],
|
|
143
|
+
[115, 171, 32],
|
|
144
|
+
[101, 181, 67],
|
|
145
|
+
[149, 137, 119],
|
|
146
|
+
[37, 142, 183],
|
|
147
|
+
[183, 130, 175],
|
|
148
|
+
[168, 125, 133],
|
|
149
|
+
[124, 142, 87],
|
|
150
|
+
[236, 156, 171],
|
|
151
|
+
[232, 194, 91],
|
|
152
|
+
[219, 200, 69],
|
|
153
|
+
[144, 219, 34],
|
|
154
|
+
[219, 95, 187],
|
|
155
|
+
[145, 154, 217],
|
|
156
|
+
[165, 185, 100],
|
|
157
|
+
[127, 238, 163],
|
|
158
|
+
[224, 178, 198],
|
|
159
|
+
[119, 153, 120],
|
|
160
|
+
[124, 212, 92],
|
|
161
|
+
[172, 161, 105],
|
|
162
|
+
[231, 155, 135],
|
|
163
|
+
[157, 132, 101],
|
|
164
|
+
[122, 185, 146],
|
|
165
|
+
[53, 166, 51],
|
|
166
|
+
[70, 163, 90],
|
|
167
|
+
[150, 190, 213],
|
|
168
|
+
[210, 107, 60],
|
|
169
|
+
[166, 152, 185],
|
|
170
|
+
[159, 194, 159],
|
|
171
|
+
[39, 141, 222],
|
|
172
|
+
[202, 176, 161],
|
|
173
|
+
[95, 140, 229],
|
|
174
|
+
[168, 142, 87],
|
|
175
|
+
[93, 170, 203],
|
|
176
|
+
[159, 142, 54],
|
|
177
|
+
[14, 168, 39],
|
|
178
|
+
[94, 150, 149],
|
|
179
|
+
[187, 206, 136],
|
|
180
|
+
[157, 224, 166],
|
|
181
|
+
[235, 158, 208],
|
|
182
|
+
[109, 232, 216],
|
|
183
|
+
[141, 201, 87],
|
|
184
|
+
[208, 124, 118],
|
|
185
|
+
[142, 125, 214],
|
|
186
|
+
[19, 237, 174],
|
|
187
|
+
[72, 219, 41],
|
|
188
|
+
[234, 102, 111],
|
|
189
|
+
[168, 142, 79],
|
|
190
|
+
[188, 135, 35],
|
|
191
|
+
[95, 155, 143],
|
|
192
|
+
[148, 173, 116],
|
|
193
|
+
[223, 112, 95],
|
|
194
|
+
[228, 128, 236],
|
|
195
|
+
[206, 114, 54],
|
|
196
|
+
[195, 119, 88],
|
|
197
|
+
[235, 140, 94],
|
|
198
|
+
[235, 202, 125],
|
|
199
|
+
[233, 155, 153],
|
|
200
|
+
[214, 214, 238],
|
|
201
|
+
[246, 200, 35],
|
|
202
|
+
[151, 125, 171],
|
|
203
|
+
[132, 145, 172],
|
|
204
|
+
[131, 142, 118],
|
|
205
|
+
[199, 126, 150],
|
|
206
|
+
[61, 162, 123],
|
|
207
|
+
[58, 176, 151],
|
|
208
|
+
[215, 141, 69],
|
|
209
|
+
[225, 154, 220],
|
|
210
|
+
[220, 77, 167],
|
|
211
|
+
[233, 161, 64],
|
|
212
|
+
[130, 221, 137],
|
|
213
|
+
[81, 191, 129],
|
|
214
|
+
[169, 162, 140],
|
|
215
|
+
[174, 177, 222],
|
|
216
|
+
[236, 174, 47],
|
|
217
|
+
[233, 188, 180],
|
|
218
|
+
[69, 222, 172],
|
|
219
|
+
[71, 232, 93],
|
|
220
|
+
[118, 211, 238],
|
|
221
|
+
[157, 224, 83],
|
|
222
|
+
[218, 105, 73],
|
|
223
|
+
[126, 169, 36]
|
|
224
|
+
].freeze
|
|
225
|
+
|
|
226
|
+
def self.key = :iwanthue
|
|
227
|
+
|
|
228
|
+
def initialize
|
|
229
|
+
super(IWANTHUE_COLORS)
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NamePlate
|
|
4
|
+
module Colors
|
|
5
|
+
module Palettes
|
|
6
|
+
# A "light side" Jedi-inspired palette
|
|
7
|
+
class JediLight < Palette
|
|
8
|
+
COLORS = [
|
|
9
|
+
[255, 255, 255], # pure white
|
|
10
|
+
[0, 87, 183], # Jedi blue
|
|
11
|
+
[114, 137, 218], # softer blue
|
|
12
|
+
[0, 204, 255], # cyan/saber glow
|
|
13
|
+
[255, 214, 10], # light yellow/gold
|
|
14
|
+
[173, 216, 230], # pale blue
|
|
15
|
+
[192, 192, 192] # silver
|
|
16
|
+
].freeze
|
|
17
|
+
|
|
18
|
+
def self.key = :jedi_light
|
|
19
|
+
|
|
20
|
+
def initialize
|
|
21
|
+
super(COLORS)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NamePlate
|
|
4
|
+
module Colors
|
|
5
|
+
module Palettes
|
|
6
|
+
# Inspired by Monokai theme
|
|
7
|
+
class Monokai < Palette
|
|
8
|
+
COLORS = [
|
|
9
|
+
[39, 40, 34], # background
|
|
10
|
+
[248, 248, 242], # foreground
|
|
11
|
+
[249, 38, 114], # pink
|
|
12
|
+
[166, 226, 46], # green
|
|
13
|
+
[253, 151, 31], # orange
|
|
14
|
+
[102, 217, 239], # cyan
|
|
15
|
+
[174, 129, 255], # purple
|
|
16
|
+
[230, 219, 116] # yellow
|
|
17
|
+
].freeze
|
|
18
|
+
|
|
19
|
+
def self.key = :monokai
|
|
20
|
+
|
|
21
|
+
def initialize
|
|
22
|
+
super(COLORS)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NamePlate
|
|
4
|
+
module Colors
|
|
5
|
+
module Palettes
|
|
6
|
+
# A soft pastel theme
|
|
7
|
+
class Pastel < Palette
|
|
8
|
+
COLORS = [
|
|
9
|
+
[255, 179, 186], # light pink
|
|
10
|
+
[255, 223, 186], # peach
|
|
11
|
+
[255, 255, 186], # light yellow
|
|
12
|
+
[186, 255, 201], # mint
|
|
13
|
+
[186, 225, 255] # baby blue
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
def self.key = :pastel
|
|
17
|
+
|
|
18
|
+
def initialize
|
|
19
|
+
super(COLORS)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "colors/palette"
|
|
4
|
+
|
|
5
|
+
# Auto-require all palette classes
|
|
6
|
+
Dir[File.join(__dir__ || Dir.pwd, "colors", "palettes", "*.rb")].sort.each { |f| require f }
|
|
7
|
+
|
|
8
|
+
module NamePlate
|
|
9
|
+
module Colors
|
|
10
|
+
# Lazily build registry from all subclasses of Palette
|
|
11
|
+
# @return [Hash{String => NamePlate::Colors::Palette}] The registry of palettes.
|
|
12
|
+
# use NamePlate::Colors.registry to access it.
|
|
13
|
+
def self.registry
|
|
14
|
+
@registry ||= Palettes.constants.map do |const|
|
|
15
|
+
klass = Palettes.const_get(const)
|
|
16
|
+
|
|
17
|
+
next unless klass.is_a?(Class) && klass < Palette
|
|
18
|
+
[klass.key, klass.new]
|
|
19
|
+
end.compact.to_h.freeze
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.for(username)
|
|
23
|
+
palette = registry.fetch(NamePlate.colors_palette) do
|
|
24
|
+
raise ArgumentError, "Unknown palette: #{NamePlate.colors_palette}"
|
|
25
|
+
end
|
|
26
|
+
palette.pick(username)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Validate a custom palette of colors.
|
|
30
|
+
#
|
|
31
|
+
# @param [Array[Integer]] palette The custom palette of colors.
|
|
32
|
+
# @return [Boolean] Whether the custom palette is valid.
|
|
33
|
+
def self.valid_custom_palette?(palette)
|
|
34
|
+
return false if palette.nil?
|
|
35
|
+
return false unless palette.is_a?(Array)
|
|
36
|
+
return false unless palette.all? { |c| c.is_a?(String) && c.match?(/\A#(?:[0-9a-fA-F]{3}){1,2}\z/) }
|
|
37
|
+
return false if palette.size < 2
|
|
38
|
+
return false if palette.size > 20
|
|
39
|
+
true
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NamePlate
|
|
4
|
+
# Configuration settings for NamePlate.
|
|
5
|
+
# These can be set globally via the {NamePlate.configure} block, or
|
|
6
|
+
# on a per-invocation basis via the options hash.
|
|
7
|
+
# @example Set global configuration
|
|
8
|
+
# NamePlate.configure do |config|
|
|
9
|
+
# config.cache_base_path = "public/system/nameplate" # defaults to "tmp/nameplate" if unset
|
|
10
|
+
# config.font = "/path/to/font.ttf" # defaults to {Avatar::FONT_FILE} if unset
|
|
11
|
+
# config.fill_color = [255, 255, 255] # defaults to {Avatar::FILL_COLOR} if unset
|
|
12
|
+
# config.colors_palette = :google # defaults to :google
|
|
13
|
+
# config.custom_palette = [[255, 255, 255], [0, 0, 0]] # required if colors_palette is :custom
|
|
14
|
+
# config.weight = 300 # defaults to 300
|
|
15
|
+
# config.annotate_position = "-0+5" # defaults to "-0+5"
|
|
16
|
+
# config.letters_count = 1 # defaults to 1
|
|
17
|
+
# config.pointsize = 140 # defaults to 140
|
|
18
|
+
# end
|
|
19
|
+
#
|
|
20
|
+
module Configuration
|
|
21
|
+
def cache_base_path
|
|
22
|
+
@cache_base_path
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def cache_base_path=(v)
|
|
26
|
+
@cache_base_path = v
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def font
|
|
30
|
+
@font || Avatar::FONT_FILE
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def font=(v)
|
|
34
|
+
@font = v
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def fill_color
|
|
38
|
+
@fill_color || Avatar::FILL_COLOR
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def fill_color=(v)
|
|
42
|
+
@fill_color = v
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def colors_palette
|
|
46
|
+
@colors_palette ||= :google
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Set the color palette to use.
|
|
50
|
+
#
|
|
51
|
+
# @param [Symbol, Array<Array<Integer>>] v The color palette to use.
|
|
52
|
+
# @return [Symbol, Array<Array<Integer>>] The color palette being used.
|
|
53
|
+
def colors_palette=(v)
|
|
54
|
+
sym = v.to_sym
|
|
55
|
+
raise ArgumentError, "Unknown palette: #{v.inspect}" unless Colors.registry.key?(sym)
|
|
56
|
+
@colors_palette = sym
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def custom_palette
|
|
60
|
+
@custom_palette ||= nil
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Set a custom palette of colors to use when colors_palette is :custom
|
|
64
|
+
#
|
|
65
|
+
# @param [Array[Integer]] v The custom palette of colors.
|
|
66
|
+
# @return [Array[Integer]] The custom palette of colors.
|
|
67
|
+
def custom_palette=(v)
|
|
68
|
+
@custom_palette = v
|
|
69
|
+
if @custom_palette.nil? && @colors_palette == :custom
|
|
70
|
+
raise "Missing Custom Palette, please set config.custom_palette if using :custom"
|
|
71
|
+
end
|
|
72
|
+
if Colors.valid_custom_palette?(@custom_palette)
|
|
73
|
+
raise "Invalid Custom Palette, please update config.custom_palette"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def weight
|
|
78
|
+
@weight ||= 300
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def weight=(v)
|
|
82
|
+
@weight = v
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def annotate_position
|
|
86
|
+
@annotate_position ||= "-0+5"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def annotate_position=(v)
|
|
90
|
+
@annotate_position = v
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def letters_count
|
|
94
|
+
@letters_count ||= 1
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def letters_count=(v)
|
|
98
|
+
@letters_count = v
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def pointsize
|
|
102
|
+
@pointsize ||= 140
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def pointsize=(v)
|
|
106
|
+
@pointsize = v
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NamePlate
|
|
4
|
+
# Mixin for models that "have an avatar".
|
|
5
|
+
#
|
|
6
|
+
# Example:
|
|
7
|
+
# class User
|
|
8
|
+
# include NamePlate::HasAvatar
|
|
9
|
+
# attr_accessor :name
|
|
10
|
+
# end
|
|
11
|
+
#
|
|
12
|
+
# user = User.new.tap { |u| u.name = "Tony" }
|
|
13
|
+
# user.avatar_path(128)
|
|
14
|
+
# # => "public/system/nameplate/2/T/226_95_81/128.png"
|
|
15
|
+
#
|
|
16
|
+
module HasAvatar
|
|
17
|
+
# Return the filesystem path to the generated avatar
|
|
18
|
+
#
|
|
19
|
+
# @param size [Integer] size in px (default 64)
|
|
20
|
+
# @return [String] path to avatar image
|
|
21
|
+
def avatar_path(size = 64)
|
|
22
|
+
NamePlate::Avatar.generate(username, size)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Return the URL path to the generated avatar
|
|
26
|
+
#
|
|
27
|
+
# @param size [Integer] size in px (default 64)
|
|
28
|
+
# @return [String] URL for avatar image
|
|
29
|
+
def avatar_url(size = 64)
|
|
30
|
+
NamePlate.path_to_url(avatar_path(size))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "mini_magick"
|
|
4
|
+
|
|
5
|
+
module NamePlate
|
|
6
|
+
module Image
|
|
7
|
+
# Resizes images with MiniMagick.
|
|
8
|
+
#
|
|
9
|
+
# Responsibility: take a source image and produce a resized
|
|
10
|
+
# version that fits the requested WxH, centered, with transparent padding.
|
|
11
|
+
#
|
|
12
|
+
# Used by {Avatar::Generator} when a non-fullsize avatar is requested.
|
|
13
|
+
class Resize
|
|
14
|
+
# Initializes a new Resize object.
|
|
15
|
+
#
|
|
16
|
+
# @param [String] from path to the source image file
|
|
17
|
+
# @param [String] to path to the destination image file
|
|
18
|
+
# @param [Integer] width target width in pixels
|
|
19
|
+
# @param [Integer] height target height in pixels
|
|
20
|
+
def initialize(from:, to:, width:, height:)
|
|
21
|
+
@from = from
|
|
22
|
+
@to = to
|
|
23
|
+
@width = width
|
|
24
|
+
@height = height
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.call(from:, to:, width:, height:)
|
|
28
|
+
new(from:, to:, width:, height:).resize!
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Entry point to resize an image.
|
|
32
|
+
#
|
|
33
|
+
# @param from [String] path to the source image file
|
|
34
|
+
# @param to [String] path to the destination image file
|
|
35
|
+
# @param width [Integer] target width in pixels
|
|
36
|
+
# @param height [Integer] target height in pixels
|
|
37
|
+
# @return [NamePlate::Results::SuccessResult, NamePlate::Results::FailureResult]
|
|
38
|
+
def resize!
|
|
39
|
+
validate_inputs!
|
|
40
|
+
process_resize
|
|
41
|
+
rescue => e
|
|
42
|
+
failure_result(e, from:, to:, width:, height:)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
attr_reader :from, :to, :width, :height
|
|
48
|
+
|
|
49
|
+
# Validates the input parameters.
|
|
50
|
+
#
|
|
51
|
+
# @return [void] if valid
|
|
52
|
+
# @raise [ArgumentError] if any parameter is invalid
|
|
53
|
+
def validate_inputs!
|
|
54
|
+
raise ArgumentError, "Source file not found: #{from}" unless File.exist?(from)
|
|
55
|
+
raise ArgumentError, "Width must be positive integer" unless width.is_a?(Integer) && width.positive?
|
|
56
|
+
raise ArgumentError, "Height must be positive integer" unless height.is_a?(Integer) && height.positive?
|
|
57
|
+
raise ArgumentError, "Destination path cannot be empty" if to.to_s.strip.empty?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Processes the image resizing.
|
|
61
|
+
#
|
|
62
|
+
# @return [NamePlate::Results::SuccessResult, NamePlate::Results::FailureResult]
|
|
63
|
+
def process_resize
|
|
64
|
+
image = MiniMagick::Image.open(from)
|
|
65
|
+
|
|
66
|
+
image.combine_options do |c|
|
|
67
|
+
c.background "transparent"
|
|
68
|
+
c.gravity "center"
|
|
69
|
+
c.thumbnail "#{width}x#{height}^"
|
|
70
|
+
c.extent "#{width}x#{height}"
|
|
71
|
+
c.unsharp "2x0.5+0.7+0"
|
|
72
|
+
c.quality 98
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
image.write(to)
|
|
76
|
+
success_result(to)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Construct a SuccessResult with the given path.
|
|
80
|
+
#
|
|
81
|
+
# @param [String] path the path to the resized image file
|
|
82
|
+
#
|
|
83
|
+
# @return [NamePlate::Results::SuccessResult] the success result
|
|
84
|
+
def success_result(path)
|
|
85
|
+
NamePlate::Results::SuccessResult.new(value: {path:})
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Construct a FailureResult with the given exception and context.
|
|
89
|
+
#
|
|
90
|
+
# @param [StandardError] exception the raised exception
|
|
91
|
+
# @param [String] from path to the source image file
|
|
92
|
+
# @param [String] to path to the destination image file
|
|
93
|
+
# @param [Integer] width target width in pixels
|
|
94
|
+
# @param [Integer] height target height in pixels
|
|
95
|
+
#
|
|
96
|
+
# @return [NamePlate::Results::FailureResult] the failure result
|
|
97
|
+
def failure_result(exception, from:, to:, width:, height:)
|
|
98
|
+
NamePlate::Results::FailureResult.new(
|
|
99
|
+
error: {
|
|
100
|
+
message: "Image resize failed: #{exception.message}",
|
|
101
|
+
exception: exception,
|
|
102
|
+
from: from,
|
|
103
|
+
to: to,
|
|
104
|
+
width: width,
|
|
105
|
+
height: height
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NamePlate
|
|
4
|
+
module Results
|
|
5
|
+
# Represents a failed operation result.
|
|
6
|
+
#
|
|
7
|
+
# Provides a consistent API for checking failure
|
|
8
|
+
# and accessing error details.
|
|
9
|
+
class FailureResult
|
|
10
|
+
attr_reader :error
|
|
11
|
+
|
|
12
|
+
def initialize(error:)
|
|
13
|
+
@error = error
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @return [Boolean]
|
|
17
|
+
def success?
|
|
18
|
+
false
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @return [Boolean]
|
|
22
|
+
def failure(argv, stdout, stderr, status)
|
|
23
|
+
NamePlate::Results::FailureResult.new(
|
|
24
|
+
error: {
|
|
25
|
+
message: "Command failed",
|
|
26
|
+
argv: argv,
|
|
27
|
+
stdout: stdout,
|
|
28
|
+
stderr: stderr,
|
|
29
|
+
status: status
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|