discourse/lib/letter_avatar.rb
Josh Soref 59097b207f
DEV: Correct typos and spelling mistakes (#12812)
Over the years we accrued many spelling mistakes in the code base. 

This PR attempts to fix spelling mistakes and typos in all areas of the code that are extremely safe to change 

- comments
- test descriptions
- other low risk areas
2021-05-21 11:43:47 +10:00

347 lines
8.0 KiB
Ruby

# frozen_string_literal: true
class LetterAvatar
class Identity
attr_accessor :color, :letter
def self.from_username(username)
identity = new
identity.color = LetterAvatar::COLORS[
Digest::MD5.hexdigest(username)[0...15].to_i(16) % LetterAvatar::COLORS.length
]
identity.letter = username[0].upcase
identity
end
end
# BUMP UP if avatar algorithm changes
VERSION = 5
# CHANGE these values to support more pixel ratios
FULLSIZE = 120 * 3
POINTSIZE = 280
class << self
def version
"#{VERSION}_#{image_magick_version}"
end
def cache_path
"tmp/letter_avatars/#{version}"
end
def generate(username, size, opts = nil)
DistributedMutex.synchronize("letter_avatar_#{version}_#{username}") do
identity = (opts && opts[:identity]) || LetterAvatar::Identity.from_username(username)
cache = true
cache = false if opts && opts[:cache] == false
size = FULLSIZE if size > FULLSIZE
filename = cached_path(identity, size)
return filename if cache && File.exists?(filename)
fullsize = fullsize_path(identity)
generate_fullsize(identity) if !cache || !File.exists?(fullsize)
# Optimizing here is dubious, it can save up to 2x for large images (eg 359px)
# BUT... we are talking 2400 bytes down to 1200 bytes, both fit in one packet
# The cost of this is huge, its a 40% perf hit
OptimizedImage.resize(fullsize, filename, size, size)
filename
end
end
def cached_path(identity, size)
dir = "#{cache_path}/#{identity.letter}/#{identity.color.join("_")}"
FileUtils.mkdir_p(dir)
File.expand_path "#{dir}/#{size}.png"
end
def fullsize_path(identity)
File.expand_path cached_path(identity, FULLSIZE)
end
def generate_fullsize(identity)
color = identity.color
letter = identity.letter
filename = fullsize_path(identity)
instructions = %W{
-size #{FULLSIZE}x#{FULLSIZE}
xc:#{to_rgb(color)}
-pointsize #{POINTSIZE}
-fill #FFFFFFCC
-font Helvetica
-gravity Center
-annotate -0+26 #{letter}
-depth 8
#{filename}
}
Discourse::Utils.execute_command('convert', *instructions)
## do not optimize image, it will end up larger than original
filename
end
def to_rgb(color)
r, g, b = color
"rgb(#{r},#{g},#{b})"
end
def image_magick_version
@image_magick_version ||=
begin
Thread.new do
sleep 2
cleanup_old
end
Digest::MD5.hexdigest(`convert --version` << `convert -list font`)
end
end
def cleanup_old
begin
skip = File.basename(cache_path)
parent_path = File.dirname(cache_path)
Dir.entries(parent_path).each do |path|
unless ['.', '..'].include?(path) || path == skip
FileUtils.rm_rf(parent_path + "/" + path)
end
end
rescue Errno::ENOENT
# no worries, folder doesn't exists
end
end
end
# palette of optimally distinct colors
# cf. http://tools.medialab.sciences-po.fr/iwanthue/index.php
# parameters used:
# - H: 0 - 360
# - C: 0 - 2
# - L: 0.75 - 1.5
COLORS = [[198, 125, 40],
[61, 155, 243],
[74, 243, 75],
[238, 89, 166],
[52, 240, 224],
[177, 156, 155],
[240, 120, 145],
[111, 154, 78],
[237, 179, 245],
[237, 101, 95],
[89, 239, 155],
[43, 254, 70],
[163, 212, 245],
[65, 152, 142],
[165, 135, 246],
[181, 166, 38],
[187, 229, 206],
[77, 164, 25],
[179, 246, 101],
[234, 93, 37],
[225, 155, 115],
[142, 140, 188],
[223, 120, 140],
[249, 174, 27],
[244, 117, 225],
[137, 141, 102],
[75, 191, 146],
[188, 239, 142],
[164, 199, 145],
[173, 120, 149],
[59, 195, 89],
[222, 198, 220],
[68, 145, 187],
[236, 204, 179],
[159, 195, 72],
[188, 121, 189],
[166, 160, 85],
[181, 233, 37],
[236, 177, 85],
[121, 147, 160],
[234, 218, 110],
[241, 157, 191],
[62, 200, 234],
[133, 243, 34],
[88, 149, 110],
[59, 228, 248],
[183, 119, 118],
[251, 195, 45],
[113, 196, 122],
[197, 115, 70],
[80, 175, 187],
[103, 231, 238],
[240, 72, 133],
[228, 149, 241],
[180, 188, 159],
[172, 132, 85],
[180, 135, 251],
[236, 194, 58],
[217, 176, 109],
[88, 244, 199],
[186, 157, 239],
[113, 230, 96],
[206, 115, 165],
[244, 178, 163],
[230, 139, 26],
[241, 125, 89],
[83, 160, 66],
[107, 190, 166],
[197, 161, 210],
[198, 203, 245],
[238, 117, 19],
[228, 119, 116],
[131, 156, 41],
[145, 178, 168],
[139, 170, 220],
[233, 95, 125],
[87, 178, 230],
[157, 200, 119],
[237, 140, 76],
[229, 185, 186],
[144, 206, 212],
[236, 209, 158],
[185, 189, 79],
[34, 208, 66],
[84, 238, 129],
[133, 140, 134],
[67, 157, 94],
[168, 179, 25],
[140, 145, 240],
[151, 241, 125],
[67, 162, 107],
[200, 156, 21],
[169, 173, 189],
[226, 116, 189],
[133, 231, 191],
[194, 161, 63],
[241, 77, 99],
[241, 217, 53],
[123, 204, 105],
[210, 201, 119],
[229, 108, 155],
[240, 91, 72],
[187, 115, 210],
[240, 163, 100],
[178, 217, 57],
[179, 135, 116],
[204, 211, 24],
[186, 135, 57],
[223, 176, 135],
[204, 148, 151],
[116, 223, 50],
[95, 195, 46],
[123, 160, 236],
[181, 172, 131],
[142, 220, 202],
[240, 140, 112],
[172, 145, 164],
[228, 124, 45],
[135, 151, 243],
[42, 205, 125],
[192, 233, 116],
[119, 170, 114],
[158, 138, 26],
[73, 190, 183],
[185, 229, 243],
[227, 107, 55],
[196, 205, 202],
[132, 143, 60],
[233, 192, 237],
[62, 150, 220],
[205, 201, 141],
[106, 140, 190],
[161, 131, 205],
[135, 134, 158],
[198, 139, 81],
[115, 171, 32],
[101, 181, 67],
[149, 137, 119],
[37, 142, 183],
[183, 130, 175],
[168, 125, 133],
[124, 142, 87],
[236, 156, 171],
[232, 194, 91],
[219, 200, 69],
[144, 219, 34],
[219, 95, 187],
[145, 154, 217],
[165, 185, 100],
[127, 238, 163],
[224, 178, 198],
[119, 153, 120],
[124, 212, 92],
[172, 161, 105],
[231, 155, 135],
[157, 132, 101],
[122, 185, 146],
[53, 166, 51],
[70, 163, 90],
[150, 190, 213],
[210, 107, 60],
[166, 152, 185],
[159, 194, 159],
[39, 141, 222],
[202, 176, 161],
[95, 140, 229],
[168, 142, 87],
[93, 170, 203],
[159, 142, 54],
[14, 168, 39],
[94, 150, 149],
[187, 206, 136],
[157, 224, 166],
[235, 158, 208],
[109, 232, 216],
[141, 201, 87],
[208, 124, 118],
[142, 125, 214],
[19, 237, 174],
[72, 219, 41],
[234, 102, 111],
[168, 142, 79],
[188, 135, 35],
[95, 155, 143],
[148, 173, 116],
[223, 112, 95],
[228, 128, 236],
[206, 114, 54],
[195, 119, 88],
[235, 140, 94],
[235, 202, 125],
[233, 155, 153],
[214, 214, 238],
[246, 200, 35],
[151, 125, 171],
[132, 145, 172],
[131, 142, 118],
[199, 126, 150],
[61, 162, 123],
[58, 176, 151],
[215, 141, 69],
[225, 154, 220],
[220, 77, 167],
[233, 161, 64],
[130, 221, 137],
[81, 191, 129],
[169, 162, 140],
[174, 177, 222],
[236, 174, 47],
[233, 188, 180],
[69, 222, 172],
[71, 232, 93],
[118, 211, 238],
[157, 224, 83],
[218, 105, 73],
[126, 169, 36]]
end