from dataclasses import dataclass, field from typing import List, Dict from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from datetime import datetime import pandas as pd from tinydb import Query import json import sys from player import Player from config import Config from logger import logger from db import MarketDB from db import PlayerDB @dataclass class Market(): url:str = 'https://play.boobylegends.com/market/' driver:webdriver = None Cards:List[dict] = field(default_factory=list) asOf:datetime = datetime.utcnow() df:pd.DataFrame = field(default_factory=pd.DataFrame) player:Player = None def fetchData(self): logger.debug("Market Fetching Data.") self.loadPage() self.Cards=[] cards=self.driver.find_elements(By.CLASS_NAME, 'wrapper-market-card') for card in cards: Card={} try: IDs=card.find_element(By.CLASS_NAME,'titre-card').text.split('\n') Card['card-num']=int(IDs[1]) Card['name']=IDs[0] link=card.find_element(By.TAG_NAME,'a') Card['card-id'] = int(link.get_attribute('card-id')) Card['phid'] = link.get_attribute('phid') Card['level'] = link.get_attribute('level') Card['link'] = link.get_attribute('href') tierCard = card.find_element(By.CLASS_NAME,'tier-card') tierLink = tierCard.get_attribute('src') Card['tier'] = tierLink[:-4][-1].upper() Card['val']= int(card.find_element(By.CLASS_NAME,'score-card').text) Card['qty']= int(card.find_element(By.CLASS_NAME,'qty').text) Card['cost']= int(card.find_element(By.CLASS_NAME,'cost').text) self.Cards.append(Card) except Exception as e: logger.error(f"{e}\n{card.text}") self.loadDF() def initPage(self): logger.debug("Market Init Page.") self.driver = webdriver.Chrome() self.driver.get(self.url) self.driver.add_cookie(Config["cookie"]) def loadPage(self): logger.debug("Market Load Page.") if self.driver is None: self.initPage() self.driver.get(self.url) self.asOf=datetime.utcnow() def closePage(self): logger.debug("Market Close Page.") self.driver.close() def getPlayerInfo(self): logger.debug("Market Get Player Info") if self.player is None: self.player = Player() self.player.fetchData() self.player.closePage() def filterMarketCards(self,force=True): logger.debug("Market Filter Cards.") clist=[None]*152 if force: self.getPlayerInfo() Cards = self.player.Cards else: today=datetime.utcnow().strftime('%Y-%m-%d') Cards=PlayerDB.search(Query().fragment({'date':today})) if len(Cards)==0: self.getPlayerInfo() Cards = self.player.Cards for card in Cards: clist[card['card-num']]=card['stock'] js="clist={clist}\n".format(clist=json.dumps(clist)) js+=""" cards=document.getElementsByClassName('wrapper-market-card') for (var i = 0; i < cards.length; i++) { cardNum = cards.item(i).getElementsByClassName('pornstar-number')[0].outerText; innerCard = cards.item(i).getElementsByClassName('inner-market-card')[0] var stock = innerCard.getElementsByClassName('Stock')[0] if (stock){stock.innerText = "Stock: " + clist[cardNum]} else { let qty = document.createElement('div'); qty.classList.add('Stock') qty.innerText = "Stock: " + clist[cardNum] innerCard.appendChild(qty) } if (clist[cardNum].includes('CRYSTAL')){ cards.item(i).style.setProperty('Display','None'); } } """ print(js) self.driver.execute_script(js) def loadDF(self): logger.debug("Market Load DF.") self.df=pd.DataFrame(self.Cards) self.df.sort_values(by='card-num', ascending=True, inplace=True) def show(self,fields=['card-num','name','level','qty','cost'],filter=''): logger.debug("Market Show Data.") if filter != '': pdf=self.df.query(filter) else: pdf=self.df print(pdf[fields].to_string(index=False)) def commit(self): def newCard(Card): thisCard={} thisCard['date'] = today thisCard['count'] = 1 thisCard['card-num'] = Card['card-num'] thisCard['name'] = Card['name'] thisCard['qty'] = Card['qty'] thisCard['cost'] = Card['cost'] thisCard['cost-min'] = Card['cost'] thisCard['cost-max'] = Card['cost'] thisCard['level'] = Card['level'] thisCard['tier'] = Card['tier'] if Card['cost']!=0: MarketDB.insert(thisCard) def updateCard(Card): matchCard=MarketDB.search(Query().fragment({'date':today,'card-num':Card['card-num']})) if len(matchCard)==0: newCard(Card) else: thisCard=matchCard[0] newData={} newData['count']=thisCard['count']+1 newData['qty']=(thisCard['count']*thisCard['qty']+Card['qty'])/(thisCard['count']+1) newData['cost']=(thisCard['count']*thisCard['cost']+Card['cost'])/(thisCard['count']+1) if 'cost-min' not in thisCard: newData['cost-min'] = Card['cost'] elif thisCard['cost-min'] > Card['cost']: newData['cost-min'] = Card['cost'] if 'cost-max' not in thisCard: newData['cost-max'] = Card['cost'] elif thisCard['cost-max'] < Card['cost']: newData['cost-max'] = Card['cost'] if Card['cost']!=0: MarketDB.update(newData,Query().fragment({'date':today,'card-num':Card['card-num']})) logger.debug("Market Commit.") today=self.asOf.strftime('%Y-%m-%d') current=MarketDB.search(Query()['date']==today) if len(current)==0: for Card in self.Cards: newCard(Card) else: for Card in self.Cards: updateCard(Card)