| rev | 
   line source | 
| 
bsw@211
 | 
     1 local alphabet = {
 | 
| 
bsw@211
 | 
     2   "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
 | 
| 
bsw@211
 | 
     3   "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
 | 
| 
bsw@211
 | 
     4   "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
 | 
| 
bsw@211
 | 
     5   "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
 | 
| 
bsw@211
 | 
     6   "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"
 | 
| 
bsw@211
 | 
     7 }
 | 
| 
bsw@211
 | 
     8 
 | 
| 
bsw@211
 | 
     9 local function encode_base64(str)
 | 
| 
bsw@211
 | 
    10   local parts = {}
 | 
| 
bsw@211
 | 
    11   local pos = 1
 | 
| 
bsw@211
 | 
    12   local block_count = 0
 | 
| 
bsw@211
 | 
    13   while pos <= #str do
 | 
| 
bsw@211
 | 
    14     local s = string.sub(str, pos, pos + 2)
 | 
| 
bsw@211
 | 
    15     local n = 0
 | 
| 
bsw@211
 | 
    16     for i = 1, 3 do
 | 
| 
bsw@211
 | 
    17       n = n * 256
 | 
| 
bsw@211
 | 
    18       if i <= #s then
 | 
| 
bsw@211
 | 
    19         n = n + string.byte(string.sub(s, i, i))
 | 
| 
bsw@211
 | 
    20       end
 | 
| 
bsw@211
 | 
    21     end
 | 
| 
bsw@211
 | 
    22     parts[#parts+1] = alphabet[math.floor(n / 262144) + 1]
 | 
| 
bsw@211
 | 
    23     parts[#parts+1] = alphabet[math.floor(n / 4096) % 64 + 1]
 | 
| 
bsw@211
 | 
    24     if #s > 1 then
 | 
| 
bsw@211
 | 
    25       parts[#parts+1] = alphabet[math.floor(n / 64) % 64 + 1]
 | 
| 
bsw@211
 | 
    26     else
 | 
| 
bsw@211
 | 
    27       parts[#parts+1] = "="
 | 
| 
bsw@211
 | 
    28     end
 | 
| 
bsw@211
 | 
    29     if #s > 2 then
 | 
| 
bsw@211
 | 
    30       parts[#parts+1] = alphabet[n % 64 + 1]
 | 
| 
bsw@211
 | 
    31     else
 | 
| 
bsw@211
 | 
    32       parts[#parts+1] = "="
 | 
| 
bsw@211
 | 
    33     end
 | 
| 
bsw@211
 | 
    34     block_count = block_count + 1
 | 
| 
bsw@211
 | 
    35     if block_count == 19 then
 | 
| 
bsw@211
 | 
    36       --parts[#parts+1] = "\r\n"
 | 
| 
bsw@211
 | 
    37       block_count = 0
 | 
| 
bsw@211
 | 
    38     end
 | 
| 
bsw@211
 | 
    39     pos = pos + #s
 | 
| 
bsw@211
 | 
    40   end
 | 
| 
bsw@211
 | 
    41   if block_count > 0 then
 | 
| 
bsw@211
 | 
    42     --parts[#parts+1] = "\r\n"
 | 
| 
bsw@211
 | 
    43   end
 | 
| 
bsw@211
 | 
    44   return table.concat(parts)
 | 
| 
bsw@211
 | 
    45 end
 | 
| 
bsw@211
 | 
    46 
 | 
| 
bsw@211
 | 
    47 function ui.avatar(member, size)
 | 
| 
bsw@211
 | 
    48   local base64_string
 | 
| 
bsw@211
 | 
    49   
 | 
| 
bsw@211
 | 
    50   if member.avatar_base64 then
 | 
| 
bsw@211
 | 
    51     base64_string = member.avatar_base64
 | 
| 
bsw@211
 | 
    52   else
 | 
| 
bsw@211
 | 
    53     local member_image = MemberImage:by_pk(member.id, "avatar", true)
 | 
| 
bsw@211
 | 
    54     if member_image then
 | 
| 
bsw@211
 | 
    55       base64_string = encode_base64(member_image.data)
 | 
| 
bsw@211
 | 
    56     else
 | 
| 
bsw@211
 | 
    57       base64_string = "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAAwADABAREA/8QAGQABAAMBAQAAAAAAAAAAAAAAAAMGBwQC/8QAIxAAAgICAgEEAwAAAAAAAAAAAQIAAwQRBTEGEiEyYTVRcf/aAAgBAQAAPwDf4kN2TRjjd1ip/TFOTRkDdNiv/DJoiR3WCml7D0o3M55DOtzsp7HYkb9h+hHH51uDlJYjEDfuP2Jo1NgupSwdMNySJzcgC3H3gd+gzNCNMR9wBtgPuaXx4K8fQD36BOmJ5ZQ6FT0RozNeQrWrPuRegx1HH1rbn0o3RYbmlKoRAo6A0J6kGXlV4eM99vxXuVrK8uJBXHp19tKxZY1trWN8mOzFdjVWrYvyU7Es+L5cQAuRTv7WWXEyq8zGS+r4t1ODyP8AC3SgRES/+OfhaZ//2Q=="
 | 
| 
bsw@211
 | 
    58     end
 | 
| 
bsw@211
 | 
    59     member.avatar_base64 = base64_string
 | 
| 
bsw@211
 | 
    60     member:save()
 | 
| 
bsw@211
 | 
    61   end
 | 
| 
bsw@211
 | 
    62 
 | 
| 
bsw@211
 | 
    63   ui.tag{ tag = "img", attr = { src = "data:image/jpeg;base64," .. base64_string } }
 | 
| 
bsw@211
 | 
    64   
 | 
| 
bsw@211
 | 
    65 end
 | 
| 
bsw@211
 | 
    66 
 |