Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2020
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.87 KB | None | 0 0
  1. from discord.ext import tasks, commands
  2.  
  3. import requests
  4. import json
  5. import datetime
  6.  
  7.  
  8.  
  9.  
  10. class unupc(commands.Cog):
  11.     def __init__(self, bot):
  12.  
  13.         self.bot = bot
  14.         self.refreshprices_loop.start() # pylint: disable=no-member
  15.  
  16.     def refreshprices_func(self): #updates the unusual prices, writes them to a file
  17.  
  18.         with open('commands/cogs/unupc/api_key.txt', 'r') as api_key: #opens the file containing the api key (remember the core bot file is in a higher directory)
  19.             key = api_key.read() #reads the file and assings to a var
  20.             payload = {'key': key} #formats the request payload
  21.             print('Connecting to Backpack.tf API')
  22.  
  23.         request = requests.get('https://backpack.tf/api/IGetPrices/v4?', params=payload) #requests from the API with the given params
  24.         response = request.json() #formats the json retrieved from the API
  25.         if response['response']['success'] == 0: #if the request is unsuccsessful
  26.             print('Request failed')
  27.         with open('api responses/backpacktf_igetpricesv4_response.json', 'w+') as backpacktf_response: #writes the api response to a file
  28.             json.dump(response, backpacktf_response)
  29.  
  30.         print(f"Prices updated at {datetime.datetime.now()}")
  31.  
  32.  
  33.     @tasks.loop(hours=2.0) #updates the prices every 2 hours
  34.     async def refreshprices_loop(self):
  35.         self.refreshprices_func()
  36.  
  37.     @refreshprices_loop.before_loop
  38.     async def before_refreshprices(self):
  39.         await self.bot.wait_until_ready()
  40.  
  41.  
  42.     @commands.command()
  43.     async def refreshprices(self, ctx):
  44.         self.refreshprices_func()
  45.         await ctx.send('Prices updated!')
  46.  
  47.  
  48.     @commands.command() #the main unupc command
  49.     async def unupc(self, ctx, item_input): #defines the command itself itself
  50.        
  51.         def getPrices(): #calls the api and formats it for unusual price checking. returns a list of possible unusual items if successful, returns None if not
  52.             with open('api responses/backpacktf_igetpricesv4_response.json', 'r') as response_raw:
  53.                 response = json.load(response_raw)
  54.            
  55.             if response['response']['success'] == 0: #if the request was unsuccessful
  56.                 return None #doesn't need to send a message to say the request was unsuccessful, because the API will be called automatically every 2 hours
  57.             else: #if the request was successful
  58.                 unusual_item_list = [] #adds every item that be unusual to a list
  59.                 for item in response['response']['items']: #iterates through every single item
  60.                     for quality in response['response']['items'][item]['prices'].keys(): #iterates through every possible quality of the item
  61.                         if quality == '5': #if the item has can have the unusual quality (5)
  62.                             unusual_item_list.append(item) #adds the item to the list of items that can be unusual
  63.                
  64.                 unusual_item_list.sort() #sorts the list of items that can be unusual, alphabetically. helps make the command more predictable in cases where several hats start with the given hat name
  65.                 return unusual_item_list, response #returns both the list of items that can be unusual (for the hat finding), and the full response (for pricing), as a tuple
  66.  
  67.         if '.' not in ctx.message.content: #if the message doesn't contain a period
  68.             await ctx.send("Invalid command syntax: correct syntax is ``effect.hat``")
  69.             return
  70.  
  71.         item_input = item_input.split('.') #splits the params of the command at a period (correct syntax is effect.hat), to create a list with 2 entries
  72.         print(item_input) #for debugging
  73.  
  74.         getPrices_result = getPrices() #needs to be assigned like this to avoid calling the function several times
  75.         unusual_item_list = getPrices_result[0] #the list of items that can be unusual
  76.         response = getPrices_result[1] #the full response from the API
  77.  
  78.         if unusual_item_list == None:
  79.             await ctx.send("Couldn't call backpack.tf's API, something has gone mighty wrong")
  80.             return #leaves the function if it can't call the api
  81.  
  82.  
  83.  
  84.         #hat autocomplete
  85.         item_hat = None
  86.         for item in unusual_item_list: #cycles through the list of items that can be unusual
  87.             if item_input[1].lower() in item.lower(): #if the hat string is in the name of the item
  88.                 item_hat = item #sets the item_hat (base item of the hat/taunt/whatever in question) to the matching entry
  89.                 break
  90.        
  91.         if item_hat == None: #if a matching hat name isn't found, the var remains as None
  92.             await ctx.send("Couldn't find a hat with that name. Make sure you're using correct syntax (``effect.hat``)")
  93.             return #leaves the function
  94.  
  95.  
  96.  
  97.         #effect autocomplete
  98.         item_effect = None
  99.         effects_dict = {"Nebula":"99","Burning Flames":"13","Spellbound":"74","It's A Secret To Everybody":"46","Scorching Flames":"14","Harvest Moon":"45","Arcana":"73","Abduction":"91","Sunbeams":"17","Darkblaze":"79","Bonzo The All-Gnawing":"81","Poisoned Shadows":"76","Knifestorm":"43","Stormy 13th Hour":"47","Hellfire":"78","Cloudy Moon":"38","Energy Orb":"704","Misty Skull":"44","Anti-Freeze":"69","Chiroptera Venenata":"75","Roboactive":"72","Demonflame":"80","Atomic":"92","Something Burning This Way Comes":"77","Galactic Codex":"97","Voltaic Hat Protector":"96","Purple Energy":"10","Death by Disco":"100","Green Energy":"9","Ether Trail":"103","Frostbite":"87","Subatomic":"93","Death at Dusk":"90","Ancient Codex":"98","Time Warp":"70","Cool":"703","Morning Glory":"89","Green Black Hole":"71","Amaranthine":"82","Magnetic Hat Protector":"95","Ghastly Ghosts Jr":"85","The Ooze":"84","Haunted Phantasm Jr":"86","Circling Heart":"19","Sulphurous":"64","Electric Hat Protector":"94","Eldritch Flame":"106","Cauldron Bubbles":"39","Stare From Beyond":"83","Haunted Ghosts":"8","Nether Trail":"104","It's a mystery to everyone":"101","Phosphorous":"63","Ancient Eldritch":"105","Flaming Lantern":"37","Hot":"701","Isotope":"702","It's a puzzle to me":"102","Vivid Plasma":"16","Molten Mallard":"88","Tesla Coil":"108","Eerie Orbiting Fire":"40","Haunted Phantasm":"3011","Searing Plasma":"15","Disco Beat Down":"62","Ghastly Ghosts":"3012","Starstorm Insomnia":"109","Starstorm Slumber":"110","Power Surge":"68","Circling Peace Sign":"18","Cloud 9":"58","Electrostatic":"67","Neutron Star":"107","Blizzardy Storm":"30","Circling TF Logo":"11","Infernal Flames":"3015","Infernal Smoke":"3016","Purple Confetti":"7","Stormy Storm":"29","Spectral Swirl":"3014","Holy Grail":"3003","Screaming Tiger":"3006","Miami Nights":"61","Green Confetti":"6","Fountain of Delight":"3005","Memory Leak":"65","Hellish Inferno":"3013","Showstopper":"3001","Terror-Watt":"57","Orbiting Fire":"33","Overclocked":"66","Kill-a-Watt":"56","Massed Flies":"12","Smoking":"35","Bubbling":"34","Steaming":"36","Orbiting Planets":"32","Dead Presidents":"60","Nuts n' Bolts":"31","'72":"3004","Aces High":"59","Skill Gotten Gains":"3007","Mega Strike":"3010","Silver Cyclone":"3009","Midnight Whirlwind":"3008"}
  100.         #some exceptions (effects that won't work on their own when entered)
  101.  
  102.         if item_input[0].lower() == 'orbiting fire': #item_effect will otherwise be set to Eerie orbiting fire, even when using the full name
  103.             item_effect = 'Orbiting Fire'
  104.         else:
  105.             print(item_input[0]) #for debugging
  106.             for effect in effects_dict.keys(): #cycles through every effect in the dict
  107.                 print(effect) #for debugging
  108.                 if item_input[0].lower() in effect.lower(): #if the key name matches the given effect name
  109.                     item_effect = effect #sets the given item's effect to the current one
  110.        
  111.         if item_effect == None: #if the specified effect couldn't be found in the dict
  112.             await ctx.send("Couldn't find an effect with that name. Make sure you're using correct syntax (``effect.hat``)")
  113.             return #quits the function
  114.  
  115.         print(item_effect, item_hat) #for... wait for it... debugging
  116.         print(effects_dict[item_effect]) #guess
  117.  
  118.         try:
  119.             price_currency = response['response']['items'][item_hat]['prices']['5']['Tradable']['Craftable'][effects_dict[item_effect]]['currency']
  120.             price_low     =  response['response']['items'][item_hat]['prices']['5']['Tradable']['Craftable'][effects_dict[item_effect]]['value']
  121.            
  122.             try: #if the item has a high value, uses that
  123.                 price_high   =   response['response']['items'][item_hat]['prices']['5']['Tradable']['Craftable'][effects_dict[item_effect]]['value_high']
  124.                 price_average = (price_low + price_high)/2 #calculates the price average off the low and high values
  125.                 if '.' in str(price_average) and str(price_average)[-1] == '0': #if the average price has a comma in it, but ends in a 0, converts it to int to remove the unnecessary decimal
  126.                     price_average = int(price_average)
  127.  
  128.                 price_message = f"The {item_effect} {item_hat} is priced at {price_low}-{price_high} {price_currency} ({price_average})"
  129.            
  130.             except KeyError: #if the item does not have a high value, uses a different format for the output message
  131.                 price_message = f"The {item_effect} {item_hat} is priced at {price_low} {price_currency}"
  132.                
  133.         except KeyError: #if a hat with the specified effect can't be found
  134.             await ctx.send("An error occured: This item is either unpriced, or doesn't exist")
  135.             return
  136.  
  137.         await ctx.send(price_message)
  138.  
  139.     def cog_unload(self):
  140.         self.refreshprices_loop.cancel()
  141.  
  142.    
  143. #consider making things more object based
  144.  
  145.  
  146. def setup(bot): #runs when the extension is loaded
  147.     bot.add_cog(unupc(bot))
  148.     print("Cog unupc loaded!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement