A simple emoji picker for rofi with multi-selection
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

extract_emojis.py 2.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import requests
  2. from bs4 import BeautifulSoup
  3. from collections import namedtuple
  4. from typing import List, Set
  5. Emoji = namedtuple('Emoji', 'char name')
  6. def fetch_emoji_html() -> BeautifulSoup:
  7. max_tries = 5
  8. for i in range(max_tries):
  9. print('Downloading emojis... try %s' % (i + 1))
  10. data = requests.get('https://unicode.org/emoji/charts-12.0/full-emoji-list.html', timeout=120) # type: requests.Response
  11. if data:
  12. break
  13. if not data:
  14. print('Could not fetch emoji data. Try again later or use another URL.')
  15. exit(10)
  16. return BeautifulSoup(data.content, 'lxml')
  17. def extract_from_html(html: BeautifulSoup) -> List[Emoji]:
  18. emojis = []
  19. for row in html.find('table').find_all('tr'):
  20. if row.th:
  21. continue
  22. emoji = row.find('td', {'class': 'chars'}).string
  23. description = row.find('td', {'class': 'name'}).string.replace('⊛ ', '')
  24. emojis.append(Emoji(emoji, description))
  25. return emojis
  26. def write_file(all_emojis: List[Emoji], human_emojis: Set[chr]):
  27. print('Writing collected emojis to file')
  28. python_file = open('emojis.py', 'w')
  29. python_file.write('emojis="""')
  30. for emoji in all_emojis:
  31. python_file.write("%s %s\n" % (emoji.char, emoji.name))
  32. python_file.write('"""\n\n')
  33. python_file.write('skin_tone_selectable_emojis={\'')
  34. python_file.write('\', \''.join(human_emojis))
  35. python_file.write('\'}\n')
  36. python_file.close()
  37. def fetch_human_emojis() -> Set[chr]:
  38. print('Downloading list of human emojis...')
  39. data = requests.get('https://unicode.org/Public/emoji/12.0/emoji-data.txt', timeout=60) # type: requests.Response
  40. started = False
  41. emojis = set()
  42. for line in data.content.decode(data.encoding).split('\n'):
  43. if not started and line != '# All omitted code points have Emoji_Modifier_Base=No ':
  44. continue
  45. started = True
  46. if started and line == '# Total elements: 120':
  47. break
  48. if started and (line.startswith('#') or len(line) == 0):
  49. continue
  50. emojis = emojis.union(extract_emojis_from_line(line))
  51. return emojis
  52. def extract_emojis_from_line(line: str) -> Set[chr]:
  53. emoji_range = line.split(';')[0].strip()
  54. try:
  55. (start, end) = emoji_range.split('..')
  56. emojis = set()
  57. for char in range(int(start, 16), int(end, 16)+1):
  58. emojis.add(chr(char))
  59. return emojis
  60. except ValueError:
  61. return set(chr(int(emoji_range, 16)))
  62. write_file(extract_from_html(fetch_emoji_html()), fetch_human_emojis())