market.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. login:bool = True
  25. def fetchData(self):
  26. logger.debug("Market Fetching Data.")
  27. self.loadPage()
  28. self.Cards=[]
  29. cards=self.driver.find_elements(By.CLASS_NAME, 'wrapper-market-card')
  30. for card in cards:
  31. Card={}
  32. try:
  33. IDs=card.find_element(By.CLASS_NAME,'titre-card').text.split('\n')
  34. Card['card-num']=int(IDs[1])
  35. Card['name']=IDs[0]
  36. link=card.find_element(By.TAG_NAME,'a')
  37. Card['card-id'] = int(link.get_attribute('card-id'))
  38. Card['phid'] = link.get_attribute('phid')
  39. Card['level'] = link.get_attribute('level')
  40. Card['link'] = link.get_attribute('href')
  41. tierCard = card.find_element(By.CLASS_NAME,'tier-card')
  42. tierLink = tierCard.get_attribute('src')
  43. Card['tier'] = tierLink[:-4][-1].upper()
  44. Card['val']= int(card.find_element(By.CLASS_NAME,'score-card').text)
  45. Card['qty']= int(card.find_element(By.CLASS_NAME,'qty').text)
  46. Card['cost']= int(card.find_element(By.CLASS_NAME,'cost').text)
  47. self.Cards.append(Card)
  48. except Exception as e:
  49. logger.error(f"{e}\n{card.text}")
  50. self.loadDF()
  51. def initPage(self):
  52. logger.debug("Market Init Page.")
  53. self.driver = webdriver.Chrome()
  54. self.driver.get(self.url)
  55. if self.login: self.driver.add_cookie(Config["cookie"])
  56. def loadPage(self):
  57. logger.debug("Market Load Page.")
  58. if self.driver is None: self.initPage()
  59. self.driver.get(self.url)
  60. self.asOf=datetime.utcnow()
  61. def closePage(self):
  62. logger.debug("Market Close Page.")
  63. self.driver.close()
  64. def getPlayerInfo(self):
  65. logger.debug("Market Get Player Info")
  66. if self.player is None: self.player = Player()
  67. self.player.fetchData()
  68. self.player.closePage()
  69. def filterMarketCards(self,force=True):
  70. logger.debug("Market Filter Cards.")
  71. clist=[None]*152
  72. if force:
  73. self.getPlayerInfo()
  74. Cards = self.player.Cards
  75. else:
  76. today=datetime.utcnow().strftime('%Y-%m-%d')
  77. Cards=PlayerDB.search(Query().fragment({'date':today}))
  78. if len(Cards)==0:
  79. self.getPlayerInfo()
  80. Cards = self.player.Cards
  81. for card in Cards: clist[card['card-num']]=card['stock']
  82. js="clist={clist}\n".format(clist=json.dumps(clist))
  83. js+="""
  84. cards=document.getElementsByClassName('wrapper-market-card')
  85. for (var i = 0; i < cards.length; i++) {
  86. cardNum = cards.item(i).getElementsByClassName('pornstar-number')[0].outerText;
  87. innerCard = cards.item(i).getElementsByClassName('inner-market-card')[0]
  88. var stock = innerCard.getElementsByClassName('Stock')[0]
  89. if (stock){stock.innerText = "Stock: " + clist[cardNum]}
  90. else {
  91. let qty = document.createElement('div');
  92. qty.classList.add('Stock')
  93. qty.innerText = "Stock: " + clist[cardNum]
  94. innerCard.appendChild(qty)
  95. }
  96. if (clist[cardNum].includes('CRYSTAL')){
  97. cards.item(i).style.setProperty('Display','None');
  98. }
  99. }
  100. """
  101. print(js)
  102. self.driver.execute_script(js)
  103. def loadDF(self):
  104. logger.debug("Market Load DF.")
  105. self.df=pd.DataFrame(self.Cards)
  106. self.df.sort_values(by='card-num', ascending=True, inplace=True)
  107. def show(self,fields=['card-num','name','level','qty','cost'],filter=''):
  108. logger.debug("Market Show Data.")
  109. if filter != '':
  110. pdf=self.df.query(filter)
  111. else:
  112. pdf=self.df
  113. print(pdf[fields].to_string(index=False))
  114. def commit(self):
  115. def newCard(Card):
  116. thisCard={}
  117. thisCard['date'] = today
  118. thisCard['count'] = 1
  119. thisCard['card-num'] = Card['card-num']
  120. thisCard['name'] = Card['name']
  121. thisCard['qty'] = Card['qty']
  122. thisCard['cost'] = Card['cost']
  123. thisCard['cost-min'] = Card['cost']
  124. thisCard['cost-max'] = Card['cost']
  125. thisCard['level'] = Card['level']
  126. thisCard['tier'] = Card['tier']
  127. if Card['cost']!=0: MarketDB.insert(thisCard)
  128. def updateCard(Card):
  129. matchCard=MarketDB.search(Query().fragment({'date':today,'card-num':Card['card-num']}))
  130. if len(matchCard)==0:
  131. newCard(Card)
  132. else:
  133. thisCard=matchCard[0]
  134. newData={}
  135. newData['count']=thisCard['count']+1
  136. newData['qty']=(thisCard['count']*thisCard['qty']+Card['qty'])/(thisCard['count']+1)
  137. newData['cost']=(thisCard['count']*thisCard['cost']+Card['cost'])/(thisCard['count']+1)
  138. if 'cost-min' not in thisCard:
  139. newData['cost-min'] = Card['cost']
  140. elif thisCard['cost-min'] > Card['cost']:
  141. newData['cost-min'] = Card['cost']
  142. if 'cost-max' not in thisCard:
  143. newData['cost-max'] = Card['cost']
  144. elif thisCard['cost-max'] < Card['cost']:
  145. newData['cost-max'] = Card['cost']
  146. if Card['cost']!=0: MarketDB.update(newData,Query().fragment({'date':today,'card-num':Card['card-num']}))
  147. logger.debug("Market Commit.")
  148. today=self.asOf.strftime('%Y-%m-%d')
  149. current=MarketDB.search(Query()['date']==today)
  150. if len(current)==0:
  151. for Card in self.Cards:
  152. newCard(Card)
  153. else:
  154. for Card in self.Cards:
  155. updateCard(Card)