cron.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import json
  2. import requests
  3. import sqlite3
  4. import sys
  5. import time
  6. import settings
  7. from pprint import pprint, pformat
  8. debug = False
  9. def dprint(text):
  10. if debug:
  11. print(text)
  12. def send_notification(maintainer, player, property, old_value, new_value):
  13. name = _name(maintainer, player)
  14. message = f"[{name} [{player}]](https://www.torn.com/profiles.php?XID={player}) property '{property}' changed from {old_value} to {new_value}"
  15. print(message)
  16. _send(maintainer, message)
  17. def _name(maintainer, player):
  18. query = """SELECT value FROM player
  19. WHERE maintainer = ?
  20. AND player = ?
  21. AND property = 'name';"""
  22. conn = sqlite3.connect(settings.db_path + '/slork.sqlite')
  23. conn.row_factory = sqlite3.Row
  24. cur = conn.cursor()
  25. cur.execute(query, (maintainer, player))
  26. name = '?'
  27. val = cur.fetchone()
  28. if val:
  29. name = val['value']
  30. conn.close()
  31. return name
  32. def _send(maintainer, message):
  33. query = """SELECT discord FROM discord WHERE maintainer = ?;"""
  34. conn = sqlite3.connect(settings.db_path + '/slork.sqlite')
  35. conn.row_factory = sqlite3.Row
  36. cur = conn.cursor()
  37. cur.execute(query, (maintainer,))
  38. discord = cur.fetchone()['discord']
  39. conn.close()
  40. message_json = {"content": message[:2000]}
  41. response = requests.post(discord, json=message_json)
  42. if response.status_code in [200, 204]:
  43. dprint("Webhook executed")
  44. time.sleep(1)
  45. else:
  46. dprint("status code {}: {}".format(response.status_code, response.content.decode("utf-8")))
  47. time.sleep(10)
  48. def update_value(maintainer, player, property, new_value):
  49. dprint(f"update_value({maintainer}, {player}, {property}, {new_value})")
  50. query = """INSERT OR REPLACE INTO player (maintainer, player, property, value)
  51. VALUES (?, ?, ?, ?)"""
  52. conn = sqlite3.connect(settings.db_path + '/slork.sqlite')
  53. conn.row_factory = sqlite3.Row
  54. cur = conn.cursor()
  55. cur.execute(query, (maintainer, player, property, new_value))
  56. conn.commit()
  57. conn.close()
  58. def update_missing_value(maintainer, player, property, value):
  59. dprint(f"update_missing_value({maintainer}, {player}, {property}, {value})")
  60. query = """INSERT OR REPLACE INTO player (maintainer, player, property, value)
  61. VALUES (?, ?, ?, ?);"""
  62. conn = sqlite3.connect(settings.db_path + '/slork.sqlite')
  63. cur = conn.cursor()
  64. cur.execute(query, (maintainer, player, property, value))
  65. conn.commit()
  66. conn.close()
  67. def cron():
  68. query_zero = """SELECT DISTINCT maintainer FROM maintainer;"""
  69. conn = sqlite3.connect(settings.db_path + '/slork.sqlite')
  70. conn.row_factory = sqlite3.Row
  71. cur = conn.cursor()
  72. query_first = """SELECT player_properties.maintainer,
  73. maintainer.api, player_properties.player,
  74. player_properties.property
  75. FROM player_properties
  76. JOIN maintainer ON player_properties.maintainer = maintainer.maintainer
  77. WHERE player_properties.maintainer = ?;"""
  78. cur.execute(query_zero)
  79. maintainers = cur.fetchall()
  80. for maintainer in maintainers:
  81. # maintainers
  82. cur.execute(query_first, (maintainer['maintainer'],))
  83. players = cur.fetchall()
  84. messages = ''
  85. for player in players:
  86. # Rows for this maintainer
  87. dprint(f"{player['maintainer']} - {player['api']} - {player['player']} - {player['property']}")
  88. url = f"https://api.torn.com/user/{player['player']}?selections=personalstats,basic,crimes,profile&key={player['api']}"
  89. dprint(url)
  90. response = requests.get(url)
  91. player_json = None
  92. dprint(response.text[:10])
  93. if response and response.text:
  94. player_json = json.loads(response.text)
  95. # pprint(faction_json)
  96. if not player_json:
  97. continue
  98. if 'error' in player_json:
  99. print(f"{player['maintainer']} -> {player['player']}")
  100. pprint(player_json)
  101. _send(player['maintainer'], f'Maintainer: {player["maintainer"]}, Player: {player["player"]} ```{pformat(player_json)}```')
  102. break
  103. # Check for changes
  104. properties = json.loads(player['property'])
  105. if 'name' not in properties:
  106. properties.append(name)
  107. # pprint(properties)
  108. query_second = """SELECT player.value, properties.parent
  109. FROM player
  110. JOIN properties ON player.property = properties.property
  111. WHERE maintainer = ?
  112. AND player = ?
  113. AND player.property = ?;"""
  114. retrieved_properties = []
  115. for property in properties:
  116. # pprint((player['maintainer'], player['player'], property,))
  117. cur.execute(query_second, (player['maintainer'], player['player'], property,))
  118. p_row = cur.fetchone()
  119. if not p_row:
  120. continue
  121. # print(f"property: '{property}' parent: '{p_row['parent']}' -> value: '{p_row['value']}'")
  122. retrieved_properties.append(property)
  123. new_value = ''
  124. try:
  125. if (p_row['parent']):
  126. new_value = player_json[p_row['parent']][property]
  127. else:
  128. new_value = player_json[property]
  129. except KeyError:
  130. new_value = 0
  131. # print(f"p_row['value']: {p_row['value']} != new_value: '{new_value}'")
  132. if str(p_row['value']) != str(new_value):
  133. if len(messages) >1750:
  134. _send(player['maintainer'], messages[:2000])
  135. messages = ''
  136. if messages:
  137. messages += '\n'
  138. name = _name(player['maintainer'], player['player'])
  139. messages += f"[{name} [{player['player']}]](https://www.torn.com/profiles.php?XID={player['player']}) property '{property}' changed from {p_row['value']} to {new_value}"
  140. # send_notification(player['maintainer'], player['player'], property, p_row['value'], new_value)
  141. update_value(player['maintainer'], player['player'], property, new_value)
  142. new_properties = []
  143. # print(f"len(properties): {len(properties)}")
  144. # print(f"len(retrieved_properties): {len(retrieved_properties)}")
  145. for item in properties:
  146. if item not in retrieved_properties:
  147. new_properties.append(item)
  148. if len(new_properties) > 0:
  149. # print(f"len(new_properties): {len(new_properties)}")
  150. for item in new_properties:
  151. query_third = """SELECT parent FROM properties where property = ?;"""
  152. cur.execute(query_third, (item,))
  153. parent = cur.fetchone()['parent']
  154. try:
  155. if (parent):
  156. value = player_json[parent][item]
  157. else:
  158. value = player_json[item]
  159. except KeyError:
  160. value = 0
  161. dprint(f"item: {item} -> value: {value}")
  162. update_missing_value(player['maintainer'], player['player'], item, value)
  163. time.sleep(2)
  164. if len(messages) > 0:
  165. dprint(messages)
  166. _send(maintainer['maintainer'], messages)
  167. conn.close()
  168. if __name__ == '__main__':
  169. cron()