market.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. from dataclasses import dataclass, field
  2. from typing import List, Dict
  3. from selenium import webdriver
  4. from selenium.webdriver.common.keys import Keys
  5. from selenium.webdriver.common.by import By
  6. from datetime import datetime
  7. import pandas as pd
  8. from tinydb import Query
  9. import json
  10. import sys
  11. from player import Player
  12. from config import Config
  13. from logger import logger
  14. from db import MarketDB
  15. from db import PlayerDB
  16. @dataclass
  17. class Market():
  18. url:str = 'https://play.boobylegends.com/market/'
  19. driver:webdriver = None
  20. Cards:List[dict] = field(default_factory=list)
  21. asOf:datetime = datetime.utcnow()
  22. df:pd.DataFrame = field(default_factory=pd.DataFrame)
  23. player:Player = None
  24. def fetchData(self):
  25. logger.debug("Market Fetching Data.")
  26. self.loadPage()
  27. self.Cards=[]
  28. cards=self.driver.find_elements(By.CLASS_NAME, 'wrapper-market-card')
  29. for card in cards:
  30. Card={}
  31. IDs=card.find_element(By.CLASS_NAME,'titre-card').text.split('\n')
  32. Card['card-num']=int(IDs[1])
  33. Card['name']=IDs[0]
  34. link=card.find_element(By.TAG_NAME,'a')
  35. Card['card-id'] = int(link.get_attribute('card-id'))
  36. Card['phid'] = link.get_attribute('phid')
  37. Card['level'] = link.get_attribute('level')
  38. Card['link'] = link.get_attribute('href')
  39. tierCard = card.find_element(By.CLASS_NAME,'tier-card')
  40. tierLink = tierCard.get_attribute('src')
  41. Card['tier'] = tierLink[:-4][-1].upper()
  42. Card['val']= int(card.find_element(By.CLASS_NAME,'score-card').text)
  43. Card['qty']= int(card.find_element(By.CLASS_NAME,'qty').text)
  44. Card['cost']= int(card.find_element(By.CLASS_NAME,'cost').text)
  45. self.Cards.append(Card)
  46. self.loadDF()
  47. def initPage(self):
  48. logger.debug("Market Init Page.")
  49. self.driver = webdriver.Chrome()
  50. self.driver.get(self.url)
  51. self.driver.add_cookie(Config["cookie"])
  52. def loadPage(self):
  53. logger.debug("Market Load Page.")
  54. if self.driver is None: self.initPage()
  55. self.driver.get(self.url)
  56. self.asOf=datetime.utcnow()
  57. def closePage(self):
  58. logger.debug("Market Close Page.")
  59. self.driver.close()
  60. def getPlayerInfo(self):
  61. logger.debug("Market Get Player Info")
  62. if self.player is None: self.player = Player()
  63. self.player.fetchData()
  64. self.player.closePage()
  65. def filterMarketCards(self,force=True):
  66. logger.debug("Market Filter Cards.")
  67. clist=[None]*152
  68. if force:
  69. self.getPlayerInfo()
  70. Cards = self.player.Cards
  71. else:
  72. today=datetime.utcnow().strftime('%Y-%m-%d')
  73. Cards=PlayerDB.search(Query().fragment({'date':today}))
  74. if len(Cards)==0:
  75. self.getPlayerInfo()
  76. Cards = self.player.Cards
  77. for card in Cards: clist[card['card-num']]=card['stock']
  78. js="clist={clist}\n".format(clist=json.dumps(clist))
  79. js+="""
  80. cards=document.getElementsByClassName('wrapper-market-card')
  81. for (var i = 0; i < cards.length; i++) {
  82. cardNum = cards.item(i).getElementsByClassName('pornstar-number')[0].outerText;
  83. innerCard = cards.item(i).getElementsByClassName('inner-market-card')[0]
  84. let qty = document.createElement('div');
  85. qty.innerText = "Stock: " + clist[cardNum]
  86. innerCard.appendChild(qty)
  87. if (clist[cardNum] == 'CRYSTAL'){
  88. cards.item(i).style.setProperty('Display','None');
  89. }
  90. }
  91. """
  92. print(js)
  93. self.driver.execute_script(js)
  94. def loadDF(self):
  95. logger.debug("Market Load DF.")
  96. self.df=pd.DataFrame(self.Cards)
  97. self.df.sort_values(by='card-num', ascending=True, inplace=True)
  98. def show(self,fields=['card-num','name','level','qty','cost'],filter=''):
  99. logger.debug("Market Show Data.")
  100. if filter != '':
  101. pdf=self.df.query(filter)
  102. else:
  103. pdf=self.df
  104. print(pdf[fields].to_string(index=False))
  105. def commit(self):
  106. logger.debug("Market Commit.")
  107. today=self.asOf.strftime('%Y-%m-%d')
  108. current=MarketDB.search(Query()['date']==today)
  109. if len(current)==0:
  110. for Card in self.Cards:
  111. thisCard={}
  112. thisCard['date'] = today
  113. thisCard['count'] = 1
  114. thisCard['card-num'] = Card['card-num']
  115. thisCard['name'] = Card['name']
  116. thisCard['qty'] = Card['qty']
  117. thisCard['cost'] = Card['cost']
  118. thisCard['cost-min'] = Card['cost']
  119. thisCard['cost-max'] = Card['cost']
  120. thisCard['level'] = Card['level']
  121. thisCard['tier'] = Card['tier']
  122. MarketDB.insert(thisCard)
  123. else:
  124. for Card in self.Cards:
  125. thisCard=MarketDB.search(Query().fragment({'date':today,'card-num':Card['card-num']}))[0]
  126. newData={}
  127. newData['count']=thisCard['count']+1
  128. newData['qty']=(thisCard['count']*thisCard['qty']+Card['qty'])/(thisCard['count']+1)
  129. newData['cost']=(thisCard['count']*thisCard['cost']+Card['cost'])/(thisCard['count']+1)
  130. if 'cost-min' not in thisCard:
  131. newData['cost-min'] = Card['cost']
  132. elif thisCard['cost-min'] > Card['cost']:
  133. newData['cost-min'] = Card['cost']
  134. if 'cost-max' not in thisCard:
  135. newData['cost-max'] = Card['cost']
  136. elif thisCard['cost-max'] < Card['cost']:
  137. newData['cost-max'] = Card['cost']
  138. MarketDB.update(newData,Query().fragment({'date':today,'card-num':Card['card-num']}))