queries.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. import random, secrets, datetime, uuid, random
  2. from slugify import slugify
  3. from common import log
  4. def create_or_get_and_update_last_event(self, table, event_type, channel_name=None, user_name=None, event_content=None, event_subject_name=None):
  5. if table == 'channel':
  6. name = channel_name
  7. if table == 'user':
  8. name = user_name
  9. record = self.db.one('SELECT * FROM rotbot_' + table + ' WHERE LOWER(name)=LOWER(%(name)s) AND network_id=%(network_id)s', name=name, network_id=self.network.id) # Look up the record.
  10. if record: # On record.
  11. fields = 'name=%(name)s, last_event_type=%(last_event_type)s' # All required fields
  12. event_channel_id = None
  13. event_user_id = None
  14. event_subject_id = None
  15. if 'event_channel' in locals():
  16. event_channel_id = get_channel_id(self, channel_name)
  17. fields += ', last_event_channel_id=%(last_event_channel_id)s'
  18. if 'event_user' in locals():
  19. event_user_id = get_user_id(self, user_name)
  20. fields += ', last_event_user_id=%(last_event_user_id)s'
  21. if 'event_content' in locals():
  22. fields += ', last_event_content=%(last_event_content)s'
  23. if 'event_subject' in locals():
  24. event_subject_id = get_user_id(self, user_name)
  25. fields +- ', last_event_subject_id=%(last_event_subject_id)s'
  26. self.db.run( # Correct capitalisation and update last event.
  27. 'UPDATE rotbot_' + table + ' SET ' + fields + ' WHERE LOWER(name)=LOWER(%(name)s) AND network_id=%(network_id)s',
  28. name=name,
  29. network_id=self.network.id,
  30. last_event_type=event_type,
  31. last_event_channel_id=event_channel_id,
  32. last_event_user_id=event_user_id,
  33. last_event_content=event_content,
  34. last_event_subject_id=event_subject_id)
  35. else: # Not on record.
  36. new_slug = slugify('%s-%s' % (name, self.network.name), max_length=50) # Create a slug from the name.
  37. slug_exists = self.db.one('SELECT id FROM rotbot_' + table + ' WHERE slug=%(slug)s', slug=new_slug) # Try to lookup a record with the proposed slug.
  38. # Keep adding random letters from the name to the slug until it is unique.
  39. while slug_exists and slug_exists <= 50:
  40. new_slug = new_slug + random.choice(name)
  41. slug_exists = self.db.one('SELECT id FROM rotbot_' + table + ' WHERE slug=%(slug)s', slug=new_slug)
  42. log.notice('Requested slug already taken on table %s with network %s: %s' % (table, self.network.name, new_slug))
  43. while slug_exists:
  44. new_slug = name + str(uuid.uuid4())
  45. slug_exists = self.db.one('SELECT id FROM rotbot_' + table + ' WHERE slug=%(slug)s', slug=new_slug)
  46. log.warning('Please clean database. Newly generated uuid4 already taken on table %s with network %s: %s' % (table, self.network.name, new_slug))
  47. fields = 'name, network_id, slug, last_event_type, last_event_datetime'
  48. values = '%(name)s, %(network_id)s, %(slug)s, %(last_event_type)s, %(last_event_datetime)s'
  49. event_datetime = datetime.datetime.now
  50. event_channel_id = None
  51. event_user_id = None
  52. event_subject_id = None
  53. if 'event_channel' in locals():
  54. event_channel_id = get_channel_id(self, channel_name)
  55. fields += ', last_event_channel_id'
  56. values += ', %(last_event_channel_id)s'
  57. if 'event_user' in locals():
  58. event_user_id = get_user_id(self, user_name)
  59. fields += ', last_event_user_id'
  60. values += ', %(last_event_user_id)s'
  61. if 'event_content' in locals():
  62. fields += ', last_event_content'
  63. values += ', %(last_event_content)s'
  64. if 'event_subject' in locals():
  65. event_subject_id = get_user_id(self, user_name)
  66. fields += ', last_event_subject_id'
  67. values += ', %(last_event_subject_id)s'
  68. if table == 'channel':
  69. fields += ', autojoin, key, games, statistic_commands, chat'
  70. values += ', %(autojoin)s, %(key)s, %(games)s, %(statistic_commands'
  71. self.db.run( # Create record.
  72. 'INSERT INTO rotbot_' + table + ' (' + fields + ') VALUES (' + values + ')s, %(chat)s)',
  73. name=name,
  74. network_id=self.network.id,
  75. slug=new_slug,
  76. last_event_type=event_type,
  77. last_event_datetime=datetime.datetime.now(),
  78. last_event_channel_id=event_channel_id,
  79. last_event_user_id=event_user_id,
  80. last_event_content=event_content,
  81. last_event_subject_id=event_subject_id,
  82. autojoin=False,
  83. key='',
  84. games=False,
  85. statistic_commands=False,
  86. chat=False,
  87. )
  88. else:
  89. fields += ', xp_spent, level, coin, coin_given, coin_spent, ap_spent, karma_correction, xp_correction, no_chat'
  90. values += ', %(xp_spent)s, %(level)s, %(coin)s, %(coin_given)s, %(coin_spent)s, %(ap_spent)s, %(karma_correction)s, %(xp_correction)s, %(no_chat)s'
  91. self.db.run( # Create record.
  92. 'INSERT INTO rotbot_' + table + ' (' + fields + ') VALUES (' + values + ')',
  93. name=name,
  94. network_id=self.network.id,
  95. slug=new_slug, last_event_type=event_type,
  96. last_event_datetime=datetime.datetime.now(),
  97. last_event_channel_id=event_channel_id,
  98. last_event_user_id=event_user_id,
  99. last_event_content=event_content,
  100. last_event_subject_id=event_subject_id,
  101. xp_spent=0,
  102. level=0,
  103. coin=0,
  104. coin_given=0,
  105. coin_spent=0,
  106. ap_spent=0,
  107. karma_correction=0,
  108. xp_correction=0,
  109. no_chat=False,
  110. )
  111. record = self.db.one('SELECT * FROM rotbot_' + table + ' WHERE slug=%(slug)s', slug=new_slug) # Lookup newly created record to return to call..
  112. return record
  113. # def get_owners(self):
  114. # return self.db.all('SELECT * FROM rotbot_owner')
  115. def is_owner(self, hostmask):
  116. return self.db.one('SELECT id FROM rotbot_owner WHERE hostmask=%(hostmask)s', hostmask=hostmask)
  117. # Channel
  118. def get_channel_id(self, channel_name):
  119. return self.db.one('SELECT id FROM rotbot_channel WHERE network_id=%(network_id)s AND LOWER(name)=LOWER(%(channel_name)s)', network_id=self.network.id, channel_name=channel_name)
  120. def get_channel_slug(self, channel_name):
  121. return self.db.one('SELECT slug FROM rotbot_channel WHERE network_id=%(network_id)s AND LOWER(name)=LOWER(%(channel_name)s)', network_id=self.network.id, channel_name=channel_name)
  122. def get_channel_setting_statistic_commands(self, channel_id):
  123. return self.db.one('SELECT statistic_commands FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
  124. def get_channel_setting_games_commands(self, channel_id):
  125. return self.db.one('SELECT games FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
  126. def get_channel_setting_chat(self, channel_id):
  127. return self.db.one('SELECT chat FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
  128. def get_autojoin_channels(self):
  129. return self.db.all('SELECT name FROM rotbot_channel WHERE network_id=%(network_id)s AND autojoin=True', network_id=self.network.id)
  130. def get_channel_last_greet(self, channel_id):
  131. return self.db.one('SELECT last_greet FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
  132. def update_channel_last_greet(self, channel_id):
  133. return self.db.run('UPDATE rotbot_channel SET last_greet=NOW() WHERE id=%(channel_id)s', channel_id=channel_id)
  134. def get_channel_last_lame(self, channel_id):
  135. return self.db.one('SELECT last_lame FROM rotbot_channel WHERE id=%(channel_id)s', channel_id=channel_id)
  136. def update_channel_last_lame(self, channel_id):
  137. return self.db.run('UPDATE rotbot_channel SET last_greet=NOW() WHERE id=%(channel_id)s', channel_id=channel_id)
  138. def get_channel_key(self, channel_name):
  139. channel_id = get_channel_id(self, channel_name) # Inperfect, make a index of the channel_name field.
  140. return self.db.one('SELECT key FROM rotbot_channel WHERE channel_id=%(channel_id)', channel_id=channel_id)
  141. def save_channel_key(self, channel_name, channel_key):
  142. channel_id = get_channel_id(self, channel_name) # Inperfect, make a index of the channel_name field.
  143. self.db.run('UPDATE key FROM rotbot_channel WHERE channel_id=%(channel_id)', channel_id=channel_id)
  144. #def update_channel_last_event(self, channel_id, event_type, event_content):
  145. # self.db.run('UPDATE rotbot_channel SET last_event_type=%(last_event_type)s, last_event_content=%(last_event_content)s WHERE channel.id=%(channel_id)s', last_event_type=event_type, last_event_content=event_content, channel_id=channel_id)
  146. def create_tempchannelkey(self, channel_id):
  147. temp_key = secrets.token_urlsafe(40)[:40]
  148. self.db.run('INSERT INTO rotbot_tempchannelkey (key, network_id, channel_id, created) VALUES (%(key)s, %(network_id)s, %(channel_id)s, %(created)s)', key=temp_key, network_id=self.network.id, channel_id=channel_id, created=datetime.datetime.now())
  149. return temp_key
  150. # User
  151. def get_user(self, user_name):
  152. return self.db.one('SELECT * FROM rotbot_user WHERE network_id=%(network_id)s AND LOWER(name)=LOWER(%(user_name)s)', network_id=self.network.id, user_name=user_name)
  153. def get_user_id(self, user_name):
  154. return self.db.one('SELECT id FROM rotbot_user WHERE network_id=%(network_id)s AND LOWER(name)=LOWER(%(user_name)s)', network_id=self.network.id, user_name=user_name)
  155. def get_user_slug(self, user_name):
  156. return self.db.one('SELECT slug FROM rotbot_user WHERE network_id=%(network_id)s AND LOWER(name)=LOWER(%(user_name)s)', network_id=self.network.id, user_name=user_name)
  157. def get_user_name(self, user_id):
  158. return self.db.one('SELECT name FROM rotbot_user WHERE id=%(id)s', id=user_id)
  159. def get_user_total_joins(self, user_id):
  160. recordset = self.db.all('SELECT amount FROM rotbot_join WHERE user_id=%(user_id)s AND network_id=%(network_id)s', user_id=user_id, network_id=self.network.id)
  161. return total_amount_in_recordset(recordset)
  162. def get_user_total_kicks(self, user_id):
  163. recordset = self.db.all('SELECT amount FROM rotbot_kick WHERE kicker_id=%(user_id)s AND network_id=%(network_id)s', user_id=user_id, network_id=self.network.id)
  164. return total_amount_in_recordset(recordset)
  165. def get_user_total_kicked(self, user_id):
  166. recordset = self.db.all('SELECT amount FROM rotbot_kick WHERE kicked_id=%(user_id)s AND network_id=%(network_id)s', user_id=user_id, network_id=self.network.id)
  167. return total_amount_in_recordset(recordset)
  168. def get_user_total_messages(self, user_id):
  169. recordset = self.db.all('SELECT amount FROM rotbot_message WHERE user_id=%(user_id)s AND network_id=%(network_id)s', user_id=user_id, network_id=self.network.id)
  170. return total_amount_in_recordset(recordset)
  171. def get_user_total_actions(self, user_id):
  172. recordset = self.db.all('SELECT amount FROM rotbot_action WHERE user_id=%(user_id)s AND network_id=%(network_id)s', user_id=user_id, network_id=self.network.id)
  173. return total_amount_in_recordset(recordset)
  174. def get_user_total_notices(self, user_id):
  175. recordset = self.db.all('SELECT amount FROM rotbot_notice WHERE user_id=%(user_id)s AND network_id=%(network_id)s', user_id=user_id, network_id=self.network.id)
  176. return total_amount_in_recordset(recordset)
  177. def get_user_total_cursewords_added(self, user_id):
  178. recordset = self.db.all('SELECT id FROM rotbot_curseword WHERE irc_user_id=%(user_id)s ', user_id=user_id)
  179. return recordset.count(recordset)
  180. def get_user_total_curseadjectives_added(self, user_id):
  181. recordset = self.db.all('SELECT id FROM rotbot_curseadjective WHERE irc_user_id=%(user_id)s', user_id=user_id)
  182. return recordset.count(recordset)
  183. def get_user_total_cursewords_banned(self, user_id):
  184. recordset = self.db.all('SELECT id FROM rotbot_curseword WHERE banned=True AND irc_user_id=%(user_id)s ', user_id=user_id)
  185. return recordset.count(recordset)
  186. def get_user_total_curseadjectives_banned(self, user_id):
  187. recordset = self.db.all('SELECT id FROM rotbot_curseadjective WHERE banned=True AND irc_user_id=%(user_id)s', user_id=user_id)
  188. return recordset.count(recordset)
  189. def get_user_last_greet(self, user_id):
  190. return self.db.one('SELECT last_greet FROM rotbot_user WHERE id=%(user_id)s', user_id=user_id)
  191. def update_user_last_greet(self, user_id):
  192. return self.db.run('UPDATE rotbot_user SET last_greet=NOW() WHERE id=%(user_id)s', user_id=user_id)
  193. def get_user_last_lame(self, user_id):
  194. return self.db.one('SELECT last_lame FROM rotbot_user WHERE id=%(user_id)s', user_id=user_id)
  195. def update_user_last_lame(self, user_id):
  196. return self.db.run('UPDATE rotbot_user SET last_lame=NOW() WHERE id=%(user_id)s', user_id=user_id)
  197. # Userchannel
  198. def get_user_channel_joins(self, user_id, channel_id):
  199. return self.db.one('SELECT amount FROM rotbot_join WHERE channel_id=%(channel_id)s AND user_id=%(user_id)s', channel_id=channel_id, user_id=user_id)
  200. def get_user_channel_kicks(self, user_id, channel_id):
  201. return self.db.one('SELECT amount FROM rotbot_kick WHERE channel_id=%(channel_id)s AND user_id=%(user_id)s', channel_id=channel_id, user_id=user_id)
  202. # Chat
  203. def random_curse(self):
  204. adjective = self.db.one('SELECT word FROM rotbot_curseadjective WHERE banned=False ORDER BY RANDOM() LIMIT 1')
  205. curse = self.db.one('SELECT word FROM rotbot_curseword WHERE banned=False ORDER BY RANDOM() LIMIT 1')
  206. # Try to hint the user of my capabilities.
  207. if not adjective:
  208. log.notice('No adjectives in the database, please add some for more colourfull language.')
  209. if not curse:
  210. log.notice('No curses in the database, please add some for more colourfull language.')
  211. return '%s %s' % (adjective, curse)
  212. def random_adjective(self):
  213. adjective = self.db.one('SELECT word FROM rotbot_curseadjective ORDER BY RANDOM() LIMIT 1')
  214. # Try to hint the user of my capabilities.
  215. if not adjective:
  216. log.notice('No adjectives in database, please add some for more colourfull language.')
  217. return self.db.one('SELECT word FROM rotbot_curseadjective ORDER BY RANDOM() LIMIT 1')
  218. def get_curse(self, word):
  219. return self.db.one('SELECT * FROM rotbot_curseword WHERE LOWER(word)=LOWER(%(word)s)')
  220. def add_curseword(self, word, user_id):
  221. user_id = get_user_id(self, user_name)
  222. return self.db.run('INSERT INTO rotbot_curseword (word, created, irc_user_id, banned) VALUES (LOWER(%(word)s), %(created)s, %(irc_user_id)s, %(banned)s)', word=word, created=datetime.datetime.now, irc_user_id=user_id, banned=False)
  223. # Statistics
  224. def update_message_statistics(self, type, channel_id, user_id):
  225. if not self.db.one('SELECT id FROM rotbot_' + type + ' WHERE channel_id=%(channel_id)s AND user_id=%(user_id)s', channel_id=channel_id ,user_id=user_id): # Not on record.
  226. self.db.run('INSERT INTO rotbot_' + type + ' (network_id, channel_id, user_id, amount) VALUES (%(network_id)s, %(channel_id)s, %(user_id)s, 1)', network_id=self.network.id, channel_id=channel_id ,user_id=user_id) # Create record.
  227. else: # On record.
  228. self.db.run('UPDATE rotbot_' + type + ' SET amount = amount +1 WHERE channel_id=%(channel_id)s AND user_id=%(user_id)s', channel_id=channel_id ,user_id=user_id) # Increment record.
  229. def increment_join(self, channel_id, user_id):
  230. if not self.db.one('SELECT id FROM rotbot_join WHERE channel_id=%(channel_id)s AND user_id=%(user_id)s', channel_id=channel_id, user_id=user_id): # No record yet
  231. self.db.run('INSERT INTO rotbot_join (network_id, channel_id, user_id, amount) VALUES (%(network_id)s, %(channel_id)s, %(user_id)s, 1)', network_id=self.network.id, channel_id=channel_id, user_id=user_id) # Create record.
  232. else:
  233. self.db.run('UPDATE rotbot_join SET amount = amount + 1 WHERE channel_id=%(channel_id)s AND user_id=%(user_id)s', channel_id=channel_id, user_id=user_id) # Update existing record.
  234. def increment_kick(self, channel_id, kicker_id, kicked_id):
  235. if not self.db.one('SELECT id FROM rotbot_kick WHERE channel_id=%(channel_id)s AND kicker_id=%(kicker_id)s AND kicked_id=%(kicked_id)s', channel_id=channel_id, kicker_id=kicker_id, kicked_id=kicked_id): # No records for kicker channel combination.
  236. self.db.run('INSERT INTO rotbot_kick (network_id, channel_id, kicker_id, kicked_id, amount) VALUES (%(network_id)s, %(channel_id)s, %(kicker_id)s, %(kicked_id)s, 1)', network_id=self.network.id, channel_id=channel_id, kicker_id=kicker_id, kicked_id=kicked_id) # Create record.
  237. else:
  238. self.db.run('UPDATE rotbot_kick SET amount = amount + 1 WHERE channel_id=%(channel_id)s AND kicker_id=%(kicker_id)s AND kicked_id=%(kicked_id)s', channel_id=channel_id, kicker_id=kicker_id, kicked_id=kicked_id) # Update record.
  239. # Game
  240. def get_top_users(self, sort):
  241. return self.db.all('SELECT id, name, level, xp_spent, coin FROM rotbot_user WHERE network_id=%(network_id)s ORDER BY ' + sort + ' DESC LIMIT 3 ', network_id=self.network.id)
  242. def get_user_gamestats(self, user_id):
  243. return self.db.one('SELECT xp_spent, level, coin, coin_given, coin_spent, ap_spent, karma_correction FROM rotbot_user WHERE id=%(id)s', id=user_id)
  244. def levelup_user(self, user_id, xp):
  245. self.db.run('UPDATE rotbot_user SET level=level+1, xp_spent=xp_spent+%(xp)s, ap_spent=ap_spent+1 WHERE id=%(user_id)s', xp=xp, user_id=user_id)
  246. coin = random.uniform(0.1, 0.9)
  247. payday(self, coin)
  248. def punish_user(self, user_id, coin, karma):
  249. self.db.run('UPDATE website_users SET coin=coin-%(coin)s, karma_correction=karma_correction-%(karma)s WHERE id=%(user_id)s', coin=coin, karma=karma, user_id=user_id)
  250. def payday(self, coin):
  251. log.info('Game payday: %s coin.' % coin)
  252. self.db.run('UPDATE rotbot_user SET coin=coin+%(coin)s WHERE network_id=%(network_id)s AND level>0', coin=coin, network_id=self.network.id)
  253. def cointransfer(self, sender_id, receiver_id, coin):
  254. self.db.run('UPDATE rotbot_user SET coin=coin-%(coin)s, coin_spent=coin_spent+%(coin)s, coin_given=coin_given+%(coin)s, ap_spent=ap_spent+1 WHERE id=%(sender_id)s', coin=coin, sender_id=sender_id)
  255. self.db.run("UPDATE rotbot_user SET coin=coin+%(coin)s WHERE id=%(user_id)s", coin=coin, id=receiver_id)
  256. coin = random.uniform(0.1, 0.3)
  257. payday(self, coin)
  258. # Common.
  259. def total_amount_in_recordset(recordset):
  260. amount = 0
  261. for record in recordset:
  262. #amount += record.amount
  263. amount += record
  264. return amount