Advertisement
Guest User

Untitled

a guest
Feb 17th, 2020
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.70 KB | None | 0 0
  1. import discord, asyncio, aiohttp, json, time, datetime, pickle, os.path, re, traceback, COC, sys, time, random
  2. from discord.ext import commands, tasks
  3. from googleapiclient.discovery import build
  4. from google_auth_oauthlib.flow import InstalledAppFlow
  5. from google.auth.transport.requests import Request
  6. from motor.motor_asyncio import AsyncIOMotorClient
  7. from sshtunnel import SSHTunnelForwarder
  8. from tinydb import TinyDB, Query, where
  9. from concurrent.futures import ThreadPoolExecutor
  10. import logging
  11.  
  12. logger = logging.getLogger('discord')
  13. logger.setLevel(logging.ERROR)
  14. handler = logging.FileHandler(filename='discord.log', encoding='utf-8', mode='w')
  15. handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
  16. logger.addHandler(handler)
  17.  
  18. home_coc_token = """REDACTED"""
  19. test_bot_token = 'REDACTED'
  20. clan_DB = TinyDB('clan_database.json')
  21. waitlist_DB = TinyDB('waitlist_database.json')
  22. bot_DB = TinyDB('bot_database.json')
  23.  
  24. client = AsyncIOMotorClient()
  25. plyr_DB = client.player_database
  26.  
  27. url = "https://api.clashofclans.com/v1/"
  28. params = None
  29. headers = {
  30.             'Accept': "application/json",
  31.             'Authorization': "Bearer " + home_coc_token
  32.         }
  33.  
  34. SCOPES = ['REDACTED']
  35.  
  36. def time_to_sync(): #returns number of seconds until sync start
  37.     #REDACTED INFORMATION
  38.     # Call the Calendar API
  39.     #FWA ID: REDACTED
  40.     now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
  41.     try:
  42.         record = bot_DB.search(where('server_id') == 321963490111913987)
  43.         test_ch = record[0]['test_ch_id']
  44.         calendar_id = record[0]['calendar_id']
  45.         events_result = service.events().list(calendarId=calendar_id, timeMin=now, #change ID in this line
  46.                                             maxResults=10, singleEvents=True,
  47.                                             orderBy='startTime').execute()
  48.         events = events_result.get('items', [])
  49.         if not events:
  50.             print(f'Sync has not posted. Time: {datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S")}')
  51.             return False
  52.         #time stamps come in format: 2019-11-25T08:00:00-08:00
  53.         sync_start = datetime.datetime.strptime(events[0]['start']['dateTime'], '%Y-%m-%dT%H:%M:%S%z')
  54.         curr_time = datetime.datetime.strptime(str(time.strftime('%Y-%m-%dT%H:%M:%S%z')), '%Y-%m-%dT%H:%M:%S%z')
  55.         dt = sync_start - curr_time
  56.         return int(dt.total_seconds())
  57.     except KeyError:
  58.         return False
  59.     except:
  60.         logger.exception("Fatal error in time_to_sync")
  61.         print(traceback.format_exc())
  62.         return False
  63.  
  64. class FWA_EvoCog(commands.Cog,name="FWA_Evo"):
  65.     def __init__(self, bot):
  66.         self.bot = bot
  67.         self.check_routine.start()
  68.  
  69.     async def cog_check(self, ctx):
  70.         return ctx.message.guild == 321963490111913987
  71.  
  72.     async def set_past_war_stats(self, clantag, data): # clan is in war
  73.         resp = data
  74.         record = clan_DB.search(where('clantag')==resp['clan']['tag'])
  75.         if record[0]['past_war']['startTime'] != resp['startTime']: #if start times are different, overwrite
  76.             members_in_war = []
  77.             for member in range(len(resp['clan']['members'])):
  78.                 members_in_war.append(resp['clan']['members'][member]['tag'][1:])
  79.             record = {'startTime': resp['startTime'],
  80.                         'endTime': resp['endTime'],
  81.                         'members': members_in_war}
  82.             clan = Query()
  83.             clan_DB.update({'past_war': record}, clan.clantag == f'#{clantag}')
  84.         else: #if start times are the same, clan is still in war and notify members to use attacks
  85.             end_time = datetime.datetime.strptime(str(resp['endTime']), "%Y%m%dT%H%M%S.%fZ")
  86.             curr_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  87.             curr_time = datetime.datetime.strptime(curr_time, "%Y-%m-%d %H:%M:%S")
  88.             dt = end_time - curr_time
  89.             deltat = int(dt.total_seconds())
  90.             if deltat < 3600: #tag roles in channels to use their attacks
  91.                 record = clan_DB.search(where('clan_stats')['name'] == resp['name'])
  92.                 channel = self.bot.get_channel(record[0]['clan_stats']['channel'])
  93.                 server = self.bot.get_guild(321963490111913987)
  94.                 role = server.get_role(record[0]["clan_stats"]["role"])
  95.                 await channel.send(f'{role.mention} there is less than 2 hours of war left. Use your attacks now for maximum loot!')
  96.             else: pass #otherwise do nothing
  97.  
  98.     async def set_current_war_stats(self, clantag, data): # clan is in prep day
  99.         resp = data
  100.         record = clan_DB.search(where('clantag')==resp['clan']['tag'])
  101.         if record[0]['current_war']['startTime'] != resp['startTime']: #if start times are different, overwrite
  102.             members_in_war = []
  103.             for member in range(len(resp['clan']['members'])):
  104.                 members_in_war.append(resp['clan']['members'][member]['tag'][1:])
  105.             record = {'startTime': resp['startTime'],
  106.                         'endTime': resp['endTime'],
  107.                         'members': members_in_war}
  108.             clan = Query()
  109.             clan_DB.update({'current_war': record, 'clan_notification': False}, clan.clantag == f'#{clantag}')
  110.         else: pass
  111.  
  112.     async def members_not_in_clan(self, clantag): #returns list of members who are not in clan that are in current war
  113.         record = clan_DB.search(where('clantag') == clantag)
  114.         members_in_war = record[0]["current_war"]["members"]
  115.         members_in_clan = []
  116.         resp = await COC.Clan(clantag).clan_members
  117.         for member in range(len(resp)):
  118.             members_in_clan.append(resp[member])
  119.         return list(set(members_in_war) - set(members_in_clan))
  120.  
  121.     async def tag_missing_members(self, clanname, clantag, channel): #tags missing members from war before sync
  122.         members_list = await self.members_not_in_clan(clantag)
  123.         if members_list == [] or members_list == None: print(f'No member to tag for {clanname}')
  124.         else:
  125.             member_id_list = []
  126.             for index in range(len(members_list)):
  127.                 account = await COC.wizbot(members_list[index]).get_id
  128.                 if account:
  129.                     member_id_list.append(int(account))
  130.                 else: pass
  131.             for index in range(len(member_id_list)):
  132.                 await channel.send(f'<@{member_id_list[index]}>, sync is coming up soon. Get back to {clanname} ASAP!')
  133.    
  134.     def cog_unload(self):
  135.         self.check_routine.cancel()
  136.  
  137.  
  138.     @tasks.loop(seconds=3600)
  139.     async def check_routine(self):
  140.         await self.bot.wait_until_ready()
  141.         record = bot_DB.search(where('server_id') == 321963490111913987)
  142.         test_ch = self.bot.get_channel(record[0]['test_ch_id'])
  143.         loop = asyncio.get_event_loop()
  144.         time_left = await loop.run_in_executor(None, time_to_sync)
  145.  
  146.         threshold = random.randint(6000,9000)
  147.         for clan in clan_DB:
  148.             try:
  149.                 status = await COC.Clan(clan['clantag'][1:]).clan_war_status
  150.                 if status['state'] == 'notInWar' or status['state']== 'warEnded':
  151.                     await test_ch.send(f'{clan["name"]} is not in war. Time: {datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S")}')
  152.                     channel = self.bot.get_channel(clan['channel'])
  153.                     server = self.bot.get_guild(321963490111913987)
  154.                     role = server.get_role(clan['role'])  
  155.                     if time_left != False and time_left <= threshold and time_left >= 0: await self.tag_missing_members(clan['name'], clan['tag'], channel)
  156.                     if time_left <= 39600 and not clan['clan_notification']:
  157.                         await channel.send(f'{role.mention}, sync time has been posted. Be back in clan no more than **10** hours from now!!')
  158.                         clan_DB.update({'clan_notification': True}, where('clantag') == f'#{clan}')
  159.                 elif status['state'] == 'preparation':
  160.                     await test_ch.send(f'{clan["name"]} is in prep. Time: {datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S")}')
  161.                     await self.set_current_war_stats(clan, status)
  162.                 elif status['state'] == 'inWar':
  163.                     await test_ch.send(f'{clan["name"]} is in war. Time: {datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S")}')
  164.                     channel = self.bot.get_channel(clan['channel'])
  165.                     server = self.bot.get_guild(321963490111913987)
  166.                     role = server.get_role(clan['role'])
  167.                     await self.set_past_war_stats(clan, status)
  168.                     if time_left != False and time_left <= threshold and time_left >= 0:
  169.                         await channel.send(f'Tagging members in {clan["name"]}. Time: {datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S")}')
  170.                         await self.tag_missing_members(clan['name'], clan['tag'], test_ch)
  171.                     if time_left != False and time_left <= 39600 and time_left >= 0 and not clan['clan_notification']:
  172.                         await channel.send(f'{role.mention}, sync time has been posted. Be back in clan no more than **10** hours from now!!')
  173.                         clan_DB.update({'clan_notification': True}, where('clantag') == f'#{clan}')
  174.                 else: print('Error')
  175.             except Exception:
  176.                 await test_ch.send(f'<@{148319665188372481}>, Unexpected error with routine at {datetime.datetime.now().strftime("%H:%M:%S")}. Check log for details.')
  177.                 logger.exception("Fatal error in main loop")
  178.                 print(traceback.format_exc())
  179.  
  180. def setup(bot):
  181.     bot.add_cog(FWA_EvoCog(bot))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement