/sigma/plugins/nihongo/wanikani/database.py

https://gitlab.com/valeth/apex-sigma-legacy · Python · 152 lines · 126 code · 20 blank · 6 comment · 19 complexity · 53e96c5ede4c319bd4f79b89c4d47c19 MD5 · raw file

  1. import requests
  2. import discord
  3. import json
  4. from lxml import html
  5. wk_base_url = 'https://www.wanikani.com/api/user/'
  6. async def get_user_data(cmd, message, key=None, username=None):
  7. user = {
  8. 'method': None,
  9. 'name': '',
  10. 'title': '',
  11. 'avatar': ['', None],
  12. 'level': 0,
  13. 'creation_date': 0,
  14. 'forums': {'posts': 0, 'topics': 0},
  15. 'srs': {
  16. 'apprentice': 0,
  17. 'guru': 0,
  18. 'master': 0,
  19. 'enlightened': 0,
  20. 'burned': 0
  21. },
  22. 'radicals': {'total': 0, 'current': 0},
  23. 'kanji': {'total': 0, 'current': 0},
  24. 'lessons': {'now': 0},
  25. 'reviews': {'now': 0, 'next_hour': 0, 'next_day': 0, 'next_date': 0},
  26. }
  27. srs_dist = None
  28. lvl_prog = None
  29. queue = None
  30. userinfo = None
  31. # if we have a key, pull data directly from API
  32. if key:
  33. url = wk_base_url + key
  34. try:
  35. srs_dist = requests.get(url + '/srs-distribution').json()
  36. lvl_prog = requests.get(
  37. url + '/level-progression').json()['requested_information']
  38. queue = requests.get(
  39. url + '/study-queue').json()['requested_information']
  40. except ConnectionError as e:
  41. cmd.bot.send_message(message.channel, 'Failed to get user data.')
  42. cmd.log.error('{:s}'.format(e))
  43. raise e
  44. userinfo = srs_dist['user_information']
  45. srs_dist = srs_dist['requested_information']
  46. user['method'] = 'api'
  47. user['radicals']['total'] = lvl_prog['radicals_total']
  48. user['radicals']['current'] = lvl_prog['radicals_progress']
  49. user['kanji']['total'] = lvl_prog['kanji_total']
  50. user['kanji']['current'] = lvl_prog['kanji_progress']
  51. user['lessons']['now'] = queue['lessons_available']
  52. user['reviews']['now'] = queue['reviews_available']
  53. user['reviews']['next_hour'] = queue['reviews_available_next_hour']
  54. user['reviews']['next_day'] = queue['reviews_available_next_day']
  55. user['reviews']['next_date'] = queue['next_review_date']
  56. # otherwise if we have a username, pull data from profile page
  57. elif username:
  58. page = requests.get(
  59. 'https://www.wanikani.com/community/people/' + username)
  60. tree = html.fromstring(page.content)
  61. script = tree.xpath('//div[@class="footer-adjustment"]/script')
  62. if script != []:
  63. script = script[0].text.strip()
  64. else:
  65. embed = discord.Embed(color=0xDB0000, title=':exclamation: Error while parsing the page, profile not found or doesn\'t exist')
  66. await cmd.bot.send_message(message.channel, None, embed=embed)
  67. return None
  68. script = script[script.find('var srsCounts'): script.find(
  69. 'Counts.fillInSrsCount(srsCounts.requested_information);')]
  70. script = script.strip()[16:-1]
  71. userinfo = json.loads(script)['user_information']
  72. srs_dist = json.loads(script)['requested_information']
  73. user['method'] = 'html'
  74. else:
  75. return None
  76. user['name'] = userinfo['username']
  77. user['title'] = userinfo['title']
  78. user['level'] = userinfo['level']
  79. user['avatar'][0] = 'https://www.gravatar.com/avatar/' + \
  80. userinfo['gravatar']
  81. user['creation_date'] = userinfo['creation_date']
  82. user['forums']['posts'] = userinfo['posts_count']
  83. user['forums']['topics'] = userinfo['topics_count']
  84. user['srs']['apprentice'] = srs_dist['apprentice']['total']
  85. user['srs']['guru'] = srs_dist['guru']['total']
  86. user['srs']['master'] = srs_dist['master']['total']
  87. user['srs']['enlightened'] = srs_dist['enlighten']['total']
  88. user['srs']['burned'] = srs_dist['burned']['total']
  89. try:
  90. user['avatar'][1] = requests.get(user['avatar'][0]).content
  91. except ConnectionError as e:
  92. cmd.bot.send_message(message.channel, 'Failed to get user avatar.')
  93. cmd.log.error('{:s}'.format(e))
  94. return user
  95. async def get_key(cmd, message, args):
  96. # if no arguments passed, pulling the ID of a caller
  97. if not args:
  98. user_id = str(message.author.id)
  99. # otherwise see if someone was mentioned
  100. elif len(message.mentions) > 0:
  101. user_id = message.mentions[0].id
  102. # otherwise, pull the username out of a message
  103. else:
  104. key = None
  105. try:
  106. username = args[0]
  107. except Exception as e:
  108. cmd.log.error(e)
  109. embed = discord.Embed(color=0xDB0000, title=':exclamation: Error while parsing the input message.')
  110. await cmd.bot.send_message(message.channel, None, embed=embed)
  111. return
  112. if 'username' not in locals():
  113. if 'user_id' not in locals():
  114. embed = discord.Embed(color=0xDB0000, title=':exclamation: No arguments passed.')
  115. await cmd.bot.send_message(message.channel, None, embed=embed)
  116. return
  117. # a username was passed
  118. else:
  119. query = {'UserID': int(user_id)}
  120. search = cmd.db.find('WaniKani', query)
  121. db_response = None
  122. for result in search:
  123. db_response = result
  124. try:
  125. key = db_response['WKAPIKey']
  126. username = db_response['WKUsername']
  127. except:
  128. embed = discord.Embed(color=0xDB0000, title=':exclamation: No Assigned Key or Username Found')
  129. embed.add_field(name='To Add A Key', value='Use `' + cmd.prefix + 'wksave key YOUR_API_KEY_HERE`')
  130. await cmd.bot.send_message(message.channel, None, embed=embed)
  131. return (None, None)
  132. return (key, username)