Skip to content

Commit 9d63b4c

Browse files
committed
fix: refactoring how selenium is called
1 parent 01c4b83 commit 9d63b4c

File tree

1 file changed

+42
-42
lines changed

1 file changed

+42
-42
lines changed

aio_etsy_stats/main.py

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import sys
88
import textwrap
99
from datetime import datetime, date, time, timedelta
10-
from os import environ, path
11-
from random import uniform, choice
10+
from os import environ
11+
from random import uniform
1212
from time import sleep
1313
from typing import NamedTuple, Optional, Tuple
1414

@@ -27,11 +27,6 @@ def get_public_ip():
2727
return response
2828

2929

30-
class DummyLogger(object):
31-
def __getattr__(self, name):
32-
return lambda *args, **kwargs: None
33-
34-
3530
class EtsyStoreStats(NamedTuple):
3631
"""Used to format stats from Etsy store"""
3732
favorite_count: Optional[int] = None
@@ -58,32 +53,35 @@ def get_timedelta_from_now(start: datetime) -> timedelta:
5853

5954
class AIOEtsyStats:
6055
"""Class to store and record stats for Etsy"""
56+
6157
def __init__(self, shop: str, default_reset_hour: int = 14, scrape_interval_minutes: int = 10,
6258
aio_username: str = None, aio_password: str = None,
6359
discord_webhook: str = None, discord_avatar_url: str = None,
6460
selenium_host: str = None, selenium_port: int = None):
61+
# region Logging
62+
logging.basicConfig()
63+
self.logger = logging.Logger(name=type(self).__name__)
64+
65+
handler_stdout = logging.StreamHandler(sys.stdout)
66+
handler_stdout.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
67+
handler_stdout.setLevel(logging.DEBUG)
68+
self.logger.addHandler(handler_stdout)
69+
# endregion
70+
71+
# region Class basics
6572
self.shop = shop
6673
self.scrape_url = f"https://www.etsy.com/shop/{shop}/sold"
6774
self.default_reset_hour = default_reset_hour
6875
self.scrape_interval_minutes = scrape_interval_minutes
6976
self.selenium_host = selenium_host
7077
self.selenium_port = selenium_port
71-
self.driver = None
72-
self.set_selenium(selenium_host=selenium_host, selenium_port=selenium_port)
78+
# endregion
7379

7480
# Get the current stats just incase this hasn't been set up before or AIO is not used
75-
self.logger = DummyLogger() # Temporary
81+
self.logger.debug(f"Getting Etsy stats for {self.shop} to use for loading")
7682
stats = self.scrape_etsy_stats()
7783

78-
# region Logging
79-
logging.basicConfig()
80-
self.logger = logging.Logger(name=type(self).__name__)
81-
82-
handler_stdout = logging.StreamHandler(sys.stdout)
83-
handler_stdout.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
84-
handler_stdout.setLevel(logging.DEBUG)
85-
self.logger.addHandler(handler_stdout)
86-
84+
# region Discord
8785
if discord_webhook:
8886
discord_handler = DiscordHandler(
8987
service_name=type(self).__name__,
@@ -127,7 +125,6 @@ def __init__(self, shop: str, default_reset_hour: int = 14, scrape_interval_minu
127125
if not existing_feed_group:
128126
self.logger.debug(f"Creating Feed Group \"{self.shop}\"")
129127
self._aio.create_group(group=Group(name=self.shop, key=self.shop.lower()))
130-
131128
feeds = [
132129
(Feed(name="Daily Order Count", key="daily-order-count"), "0"),
133130
(Feed(name="Favorite Count", key="favorite-count"), stats.favorite_count),
@@ -196,23 +193,23 @@ def _atexit(self):
196193
-# Exiting on host `{socket.gethostname()}`
197194
""").strip())
198195

199-
def set_selenium(self, selenium_host: str, selenium_port: int) -> None:
200-
self.selenium_host = selenium_host
201-
self.selenium_port = selenium_port
196+
def _get_webdriver(self):
202197
if self.selenium_host and self.selenium_port:
203-
print("Waiting up to 20s for selenium port to be open")
198+
self.logger.debug("Waiting up to 20s for selenium port to be open")
204199
start = datetime.now()
205200
while (test_port(self.selenium_host, self.selenium_port) != 0) \
206201
and (get_timedelta_from_now(start) < timedelta(seconds=20)):
207202
sleep(1)
208203

209204
if self.selenium_host and self.selenium_port:
210-
self.driver = webdriver.Remote(
211-
command_executor=f"http://{self.selenium_host}:{self.selenium_port}/wd/hub",
205+
driver = webdriver.Remote(
206+
command_executor=f"http://{self.selenium_host}:{self.selenium_port}",
212207
options=webdriver.ChromeOptions()
213208
)
214209
else:
215-
self.driver = webdriver.Chrome()
210+
driver = webdriver.Chrome()
211+
212+
return driver
216213

217214
def _get_starting_stats(self) -> dict:
218215
"""Gets starting-stats feed and parses the json to dictionary"""
@@ -222,18 +219,24 @@ def _get_starting_stats(self) -> dict:
222219

223220
def _get_selenium(self, url: str) -> Tuple[str, str]:
224221
"""Gets webpage content with selenium"""
222+
driver = None
225223
content = None
226224
title = None
227225
try:
228-
self.driver.get(url)
229-
title = self.driver.title
230-
content = self.driver.page_source
226+
driver = self._get_webdriver()
227+
driver.get(url)
228+
title = driver.title
229+
content = driver.page_source
231230

232231
if not content:
233232
self.logger.debug(f"No content for url {url}. Page title: {title}")
234233
except Exception as e:
235234
self.logger.warning(f"An error occurred getting page {url} with Selenium Firefox")
236235
self.logger.exception(e)
236+
finally:
237+
if driver:
238+
driver.close()
239+
driver.quit()
237240

238241
return title, content
239242

@@ -264,7 +267,7 @@ def _send_aio(self, feed: str, value):
264267
"""Helper function to send values to AIO and parse for errors"""
265268
if self._aio:
266269
feed = self._get_feed_name(feed=feed)
267-
270+
268271
try:
269272
self.logger.debug(f"Updating AIO feed {feed} to {value}")
270273
if isinstance(value, dict):
@@ -279,7 +282,7 @@ def _receive_aio(self, feed: str, default_value: object = None, silent: bool = F
279282
return_val = default_value
280283
if self._aio:
281284
feed = self._get_feed_name(feed=feed)
282-
285+
283286
try:
284287
response = self._aio.receive(feed=feed)
285288
if not silent:
@@ -301,15 +304,14 @@ def _reset_counts(self) -> None:
301304
self.logger.info(textwrap.dedent(f"""
302305
{type(self).__name__} for **{self.shop}**
303306
304-
-# Reset time of {self.reset_datetime} has passed
307+
-# Reset time of **{self.reset_datetime:%Y-%m-%d %H:%M:%S%z}** has passed
305308
-# Daily Order Count was `{self.daily_order_count}`
306-
-# Daily Favorites was `{self.favorite_count - self.starting_favorite_count}
309+
-# Daily Favorites was `{self.favorite_count - self.starting_favorite_count}`
307310
-# Daily Rating was `{(self.rating - self.starting_rating):4f}`
308-
-# Daily Ratings was `{self.rating_count - self.rating}`
311+
-# Daily Rating Count was `{self.rating_count - self.starting_rating_count}`
309312
-# Daily Sold was `{self.sold_count - self.starting_sold_count}`
310-
-# Next reset is {new_reset_datetime}
313+
-# Next reset is **{new_reset_datetime:%Y-%m-%d %H:%M:%S%z}**
311314
-# Public IP is `{get_public_ip()}`
312-
-# Shawn ❤️ Nicole
313315
""").strip())
314316

315317
# Update all things to be equal to current stats
@@ -428,7 +430,7 @@ def scrape_etsy_stats(self) -> EtsyStoreStats:
428430
errors += 1
429431
# endregion
430432

431-
return EtsyStoreStats(favorite_count=favorite_count, rating=rating, rating_count=rating_count,
433+
return EtsyStoreStats(favorite_count=favorite_count, rating=rating, rating_count=rating_count,
432434
sold_count=sold_count, avatar_url=avatar_url, errors=errors)
433435

434436
def _log_current_stats(self):
@@ -458,7 +460,6 @@ def collect_and_publish(self) -> None:
458460

459461
# If we passed reset_datetime, process the reset using the current stats
460462
if datetime.now() > self.reset_datetime:
461-
self.logger.info(f"Reset time of {self.reset_datetime} has been passed")
462463
self._reset_counts()
463464

464465
# region Process Stats
@@ -525,9 +526,9 @@ def _add_scheduled_job(self):
525526
"""Used to add the job. Can be called again if you have to remove it from the schedule"""
526527
minutes = self.scrape_interval_minutes
527528
if minutes > 9:
528-
schedule.every(minutes).to(minutes+5).minutes.do(self.collect_and_publish)
529+
schedule.every(minutes).to(minutes + 5).minutes.do(self.collect_and_publish)
529530
else:
530-
schedule.every(minutes).to(minutes+1).minutes.do(self.collect_and_publish)
531+
schedule.every(minutes).to(minutes + 1).minutes.do(self.collect_and_publish)
531532

532533
def main(self):
533534
"""Run this to have this run on a schedule"""
@@ -542,7 +543,6 @@ def main(self):
542543

543544

544545
if __name__ == "__main__":
545-
546546
client = AIOEtsyStats(shop=environ.get("ETSY_STORE_NAME"),
547547
default_reset_hour=int(environ.get("DEFAULT_RESET_HOUR", 14)),
548548
scrape_interval_minutes=int(environ.get("SCRAPE_INTERVAL_MINUTES", 5)),

0 commit comments

Comments
 (0)