sticker_generator.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import itertools
  2. import os
  3. import random
  4. import secrets
  5. from textwrap import TextWrapper
  6. from urllib.request import urlretrieve
  7. from PIL import Image
  8. from PIL import ImageDraw
  9. from PIL import ImageFont
  10. from .crop import crop_to_circle
  11. from .get_height import get_y_and_heights
  12. from .rectangle import rounded_rectangle
  13. """ Taken From https://github.com/pokurt/Nana-Remix/tree/
  14. 8d10285c9ba68ec127d3d4f0d6e7a67e48ca5f4d/nana/utils/sticker """
  15. COLORS = [
  16. '#F07975',
  17. '#F49F69',
  18. '#F9C84A',
  19. '#8CC56E',
  20. '#6CC7DC',
  21. '#80C1FA',
  22. '#BCB3F9',
  23. '#E181AC',
  24. ]
  25. urlretrieve(
  26. 'https://github.com/pokurt/Fonts/raw/master/NotoSansDisplay-Bold.ttf',
  27. 'wbb/modules/sticker/NotoSansDisplay-Bold.ttf',
  28. )
  29. urlretrieve(
  30. 'https://github.com/pokurt/Fonts/raw/master/OpenSans-Regular.ttf',
  31. 'wbb/modules/sticker/OpenSans-Regular.ttf',
  32. )
  33. async def create_sticker(client, message):
  34. if len(message.text) < 100:
  35. body_font_size = 25
  36. wrap_size = 40
  37. elif len(message.text) < 200:
  38. body_font_size = 20
  39. wrap_size = 45
  40. elif len(message.text) < 500:
  41. body_font_size = 17
  42. wrap_size = 50
  43. elif len(message.text) < 1000:
  44. body_font_size = 15
  45. wrap_size = 90
  46. else:
  47. body_font_size = 8
  48. wrap_size = 200
  49. font = ImageFont.truetype(
  50. 'wbb/modules/sticker/OpenSans-Regular.ttf',
  51. body_font_size,
  52. )
  53. font_who = ImageFont.truetype(
  54. 'wbb/modules/sticker/NotoSansDisplay-Bold.ttf',
  55. 24,
  56. )
  57. img = Image.new(
  58. 'RGBA',
  59. (512, 512),
  60. (255, 255, 255, 0),
  61. )
  62. draw = ImageDraw.Draw(img)
  63. draw.rounded_rectangle = rounded_rectangle
  64. wrapper = TextWrapper(
  65. width=wrap_size,
  66. break_long_words=False,
  67. replace_whitespace=False,
  68. )
  69. lines_list = [
  70. wrapper.wrap(i) for i in message.text.split('\n') if i != ''
  71. ]
  72. text_lines = list(itertools.chain.from_iterable(lines_list))
  73. y, line_heights = await get_y_and_heights(
  74. text_lines,
  75. (512, 512),
  76. 10,
  77. font,
  78. )
  79. in_y = y
  80. rec_y = (y + line_heights[0]) if wrap_size >= 40 else y
  81. for i, _ in enumerate(text_lines):
  82. rec_y += line_heights[i]
  83. await rounded_rectangle(
  84. draw,
  85. (
  86. (90, in_y),
  87. (512, rec_y + line_heights[-1]),
  88. ),
  89. 10,
  90. fill='#e0e0e0',
  91. )
  92. first = message.from_user.first_name
  93. f_user = (
  94. first
  95. + ' '
  96. + message.from_user.last_name
  97. if message.from_user.last_name else first
  98. )
  99. draw.text(
  100. (100, y),
  101. f'{f_user}',
  102. random.choice(COLORS),
  103. font=font_who,
  104. )
  105. y = (y + (line_heights[0] * (20/100))) if wrap_size >= 40 else y
  106. x = 100
  107. for i, line in enumerate(text_lines):
  108. y += line_heights[i]
  109. draw.text((x, y), line, '#211536', font=font)
  110. try:
  111. user_profile_pic = await client.get_profile_photos(
  112. message.from_user.id,
  113. )
  114. photo = await client.download_media(user_profile_pic[0].file_id)
  115. except IndexError:
  116. urlretrieve(
  117. 'https://telegra.ph/file/1d3bf9a37547be4b04dcd.jpg',
  118. 'wbb/modules/sticker/default.jpg',
  119. )
  120. photo = 'wbb/modules/sticker/default.jpg'
  121. im = Image.open(photo).convert('RGBA')
  122. im.thumbnail((60, 60))
  123. await crop_to_circle(im)
  124. img.paste(im, (20, in_y))
  125. sticker_file = f'{secrets.token_hex(2)}.webp'
  126. img.save(sticker_file)
  127. await message.reply_sticker(
  128. sticker=sticker_file,
  129. )
  130. if os.path.isfile(sticker_file):
  131. os.remove(sticker_file)