Skip to content

Commit 55e9802

Browse files
committed
prints using python logging, exception handling, requirements update
1 parent 50154e3 commit 55e9802

21 files changed

+254
-145
lines changed

Constants.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
class Constants:
2-
DEBUG = True
32
TEST_SERVER = False
3+
SASSBOT_LOG_LEVEL = 20 # DEBUG = 10, INFO = 20, WARNING = 30, ERROR = 40, CRITICAL = 50
4+
OTHER_LIBRARIES_LOG_LEVEL = 20 # DEBUG = 10, INFO = 20, WARNING = 30, ERROR = 40, CRITICAL = 50
45
if TEST_SERVER:
56
GUILD_ID =313876691082674178 #Guild ID of the discord server
67
whiteListedRoleIDs = [145802742647095296] # IDs of Roles you wish to be white listed for some commands. You can also add user IDs if you want to add an individual without a role

Database.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
from datetime import date
66
from datetime import timedelta
77
import StaticMethods
8+
import logging
9+
from Constants import Constants
810

911
class Database:
1012
def __init__(self):
11-
pass
13+
self.logger = logging.getLogger(__name__)
14+
self.logger.setLevel(Constants.SASSBOT_LOG_LEVEL)
1215

1316
def connectCursor(self):
1417
try:
@@ -19,9 +22,9 @@ def connectCursor(self):
1922
f = open("testingForLeak.txt", 'w')
2023
f.close()
2124
except Exception as e:
22-
print(e)
25+
self.logger.error(e)
2326
if "Too many open files" in str(e):
24-
print("File descriptor leak detected. Rebooting")
27+
self.logger.critical("File descriptor leak detected. Rebooting")
2528
StaticMethods.rebootServer()
2629
return conn, cur
2730

@@ -165,7 +168,7 @@ def addTempTitle(self,title: str, platform: str, accountName: str ) -> None:
165168
cur.close()
166169
conn.close()
167170
else:
168-
print("given bad account or platform. can't update title")
171+
self.logger.error("given bad account or platform. can't update title")
169172

170173
def checkAddTitleCols(self):
171174
isTitleExist = self.isColExist("platform_accounts","temp_title")
@@ -556,7 +559,7 @@ def isExists(self,query: str) -> bool:
556559
value = cur.fetchall()
557560
isExists = value[0][0]
558561
except sqlite3.OperationalError:
559-
print("error when checking if col exists, perhaps no data yet")
562+
self.logger.warning("error when checking if col exists, perhaps no data yet")
560563
cur.close()
561564
conn.close()
562565
return isExists

NoDriverBrowserCreator.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
import ctypes, os
77
import platform
88
import psutil
9-
import StaticMethods
9+
import logging
1010
from Constants import Constants
1111
from nodriver import *
1212

13+
logger = logging.getLogger(__name__)
14+
logger.setLevel(Constants.SASSBOT_LOG_LEVEL)
15+
1316
def KillUnconncetedBrowsers():
1417
PROCNAMES = ["google-chrome",
1518
"chromium",
@@ -25,9 +28,9 @@ def KillUnconncetedBrowsers():
2528
proc.terminate()
2629
except Exception as e:
2730
proc.kill()
28-
print(e)
31+
logger.warning(e)
2932
if numBrowserProcesses > 0:
30-
print(f"Tried to kill {numBrowserProcesses} browser processes.")
33+
logger.info(f"Tried to kill {numBrowserProcesses} browser processes.")
3134

3235
def getUserAgent():
3336
userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/127.0.2651.105"
@@ -37,7 +40,7 @@ def getUserAgent():
3740
userAgent = random.choice(userAgentsJson)
3841
page.close()
3942
except:
40-
print("Trouble getting user agent from jnrbsn's github. Using default")
43+
logger.warning("Trouble getting user agent from jnrbsn's github. Using default")
4144
return userAgent
4245

4346
async def GetBrowser(proxy=""):
@@ -58,7 +61,7 @@ async def GetBrowser(proxy=""):
5861
headless=toHeadless,
5962
retries = Constants.NODRIVER_BROWSER_CONNECT_RETRIES)
6063
except Exception as e:
61-
print(f"error creating browser in GetBrowser: {e}")
64+
logger.warning(f"error creating browser in GetBrowser: {e}")
6265
await asyncio.sleep(1 * Constants.NODRIVER_WAIT_MULTIPLIER)
6366
KillUnconncetedBrowsers()
6467
await asyncio.sleep(1 * Constants.NODRIVER_WAIT_MULTIPLIER)

README.MD

+6-1
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,16 @@
7979
### Known Issues
8080

8181
1. If multiple accounts are streaming on the same platform at the same time, /rebroadcast will only show an announcement for one of the accounts.
82-
2. Cam4 api ban your IP if you make too many calls from the same ip. May need to switch methods in the future.
82+
2. Cam4 will api ban your IP if you make too many calls from the same ip. May need to switch methods in the future.
8383
3. Fansly will 404 you for a period of time if you make too many requests from the same ip
8484
4. If you are in a state that requires age verification, some of these checkers wont work.
8585

8686
### Update History
87+
- 10/11/2024
88+
- Moving prints over to pythyon logging library
89+
- Improved some exception handling
90+
- Fixed file descriptor leak-- happened over a week ago but i'm confident it's gone now.
91+
- added newer versions of hikari/tanjun to requirements. No code changes so old will still work too for now.
8792
- 10/3/2024
8893
- Fixed MFC, SC, BC checkers
8994
- 9/24/2024

StaticMethods.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@
99
from datetime import date
1010
import re
1111
import tanjun
12+
import logging
13+
14+
logger = logging.getLogger(__name__)
15+
logger.setLevel(Constants.SASSBOT_LOG_LEVEL)
1216

1317
def logCommand(funcName, ctx) -> None:
1418
file = open("commandLogs.txt", 'a')
1519
date = datetime.datetime.fromtimestamp(time.time())
1620
if isinstance(ctx, tanjun.abc.SlashContext):
1721
file.write(f"{date} - {funcName} - used by {ctx.member.id} aka {ctx.member.display_name}\n")
1822
else:
19-
print("didn't get right ctx for logger")
23+
logger.warning("didn't get right ctx for command logger")
2024
file.close()
2125

2226
def resetUnfinishedConfessions():
@@ -93,7 +97,7 @@ def smartRebroadcast() -> None:
9397
lastOnlineMessage,streamStartTime,streamEndTime,isRerun = db.getPlatformsRowValues(platform)
9498
secondsSinceLastMessage = timeToSeconds(lastOnlineMessage)
9599
if secondsSinceLastMessage >= Constants.SECONDS_BETWEEN_SMART_ALERTS and streamStartTime > streamEndTime:
96-
print(f"Smart alert for {platform}")
100+
logger.info(f"Smart alert for {platform}")
97101
globals.rebroadcast[platform] = 1
98102

99103
def getMaxOnlineInPresenceDict(presDict: dict) -> int:
@@ -128,7 +132,7 @@ def getEmbedImage() -> str:
128132
twImgQue = twImgList
129133
if not twImgList:
130134
imageSrc = 'images/twitErrImg.jpg'
131-
print("adding default image for embed since nothing is on the list.")
135+
logger.info("adding default image for embed since nothing is on the image list.")
132136
elif url:
133137
imageSrc = url
134138
else:
@@ -141,7 +145,7 @@ def unPin() -> None:
141145
db.setImgPin(0, "")
142146

143147
def setRebroadcast() -> None:
144-
print("rebroadcast: On")
148+
logger.info("rebroadcast: On")
145149
globals.rebroadcast = {
146150
"chaturbate":1,
147151
"onlyfans":1,
@@ -254,9 +258,10 @@ def timeToSeconds(newTime: float) -> int:
254258
return totalTime
255259

256260
def rebootServer() -> None:
261+
logger.critical("Sassbot server rebooting from restart command or fd leak detection or scheduled restart based off TIME_BEFORE_BOT_RESTART")
257262
os.system('reboot')
258263

259264
def safeRebootServer() -> None:
260265
time.sleep(300)
261-
print("Scheduled restart is happening.\nSleeping for 300 seconds before restart, in case something goes horribly wrong")
266+
logger.warning("Scheduled restart is happening.\nSleeping for 300 seconds before restart, in case something goes horribly wrong")
262267
rebootServer()

checkers/Bongacams.py

+28-20
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
import json
55
from Constants import Constants
66
from NoDriverBrowserCreator import getUserAgent
7+
import logging
8+
9+
logger = logging.getLogger(__name__)
10+
logger.setLevel(Constants.SASSBOT_LOG_LEVEL)
711

812
def isModelOnline(bcUserName):
913
title = Constants.bcDefaultTitle
@@ -12,26 +16,30 @@ def isModelOnline(bcUserName):
1216
icon = 'images/errIcon.png'
1317
agent = getUserAgent()
1418
headers = {"User-Agent": agent}
15-
page = requests.get(f'https://bongacams.com/{bcUserName}',headers=headers)
16-
time.sleep(1)
17-
if page.status_code == 200:
18-
soup = BeautifulSoup(page.content, "html.parser")
19-
bcJson = []
20-
roomJsons = soup.find_all("script", type="application/json")
21-
for roomJson in roomJsons:
22-
if 'chatTopicOptions' in roomJson.text:
23-
bcJson = json.loads(roomJson.text)
24-
break
25-
if bcJson:
26-
if bcJson["chatTopicOptions"]["currentTopic"]:
27-
title = bcJson["chatTopicOptions"]["currentTopic"]
28-
title = title.replace('\u200b', '')
29-
title = title.replace('\r', '')
30-
title = title.replace('\n', '')
31-
icon = bcJson['chatHeaderOptions']['profileImage']
32-
icon = "https:" + icon
33-
isOnline = not bcJson['chatShowStatusOptions']['isOffline']
34-
page.close()
19+
try:
20+
page = requests.get(f'https://bongacams.com/{bcUserName}',headers=headers)
21+
time.sleep(1)
22+
if page.status_code == 200:
23+
soup = BeautifulSoup(page.content, "html.parser")
24+
bcJson = []
25+
roomJsons = soup.find_all("script", type="application/json")
26+
for roomJson in roomJsons:
27+
if 'chatTopicOptions' in roomJson.text:
28+
bcJson = json.loads(roomJson.text)
29+
break
30+
if bcJson:
31+
if bcJson["chatTopicOptions"]["currentTopic"]:
32+
title = bcJson["chatTopicOptions"]["currentTopic"]
33+
title = title.replace('\u200b', '')
34+
title = title.replace('\r', '')
35+
title = title.replace('\n', '')
36+
icon = bcJson['chatHeaderOptions']['profileImage']
37+
icon = "https:" + icon
38+
isOnline = not bcJson['chatShowStatusOptions']['isOffline']
39+
except requests.exceptions.ConnectTimeout:
40+
logger.warning("connection timed out to Bongacams. Bot detection or rate limited?")
41+
except requests.exceptions.SSLError:
42+
logger.warning("SSL Error when attempting to connect to Bomgacams")
3543
return isOnline, title, thumbUrl, icon
3644

3745

checkers/Cam4.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
import time
55
from Constants import Constants
66
from NoDriverBrowserCreator import getUserAgent
7+
import logging
8+
9+
logger = logging.getLogger(__name__)
10+
logger.setLevel(Constants.SASSBOT_LOG_LEVEL)
711

812
def isModelOnline(cam4UserName):
913
title = Constants.cam4DefaultTitle
@@ -20,9 +24,10 @@ def isModelOnline(cam4UserName):
2024
if cam4Json['online']:
2125
isOnline = True
2226
icon = cam4Json['profileImageUrl']
23-
results.close()
2427
except json.decoder.JSONDecodeError:
25-
print("cam4 api didn't respond?")
28+
logger.warning("cam4 api didn't respond?")
2629
except requests.exceptions.ConnectTimeout:
27-
print("connection timed out to cam4 api. Bot detection or rate limited?")
30+
logger.warning("connection timed out to cam4 api. Bot detection or rate limited?")
31+
except requests.exceptions.SSLError:
32+
logger.warning("SSL Error when attempting to connect to Cam4")
2833
return isOnline, title, thumbUrl, icon

checkers/Chaturbate.py

+28-20
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,41 @@
22
import requests
33
from Constants import Constants
44
import json.decoder
5+
import logging
6+
7+
logger = logging.getLogger(__name__)
8+
logger.setLevel(Constants.SASSBOT_LOG_LEVEL)
59

610
def isModelOnline(cbUserName):
711
isOnline = False
812
title = "placeholder cb title"
913
thumbUrl = ""
1014
icon = 'images/errIcon.png'
11-
onlineModels = requests.get(Constants.cbApiUrl)
12-
time.sleep(3)
1315
try:
14-
results = onlineModels.json()["results"]
15-
count = onlineModels.json()['count']
16-
iterations = 1
17-
tempLimit = 0
18-
while count > tempLimit and not isOnline:
19-
tempLimit = Constants.cbJsonLimit * iterations
20-
for result in results:
21-
if result['username'] == cbUserName:
22-
isOnline = True
23-
title = result['room_subject']
24-
#thumbUrl = result['image_url'] + "?" + str(int(time.time()))
25-
break
26-
onlineModels = requests.get(Constants.cbApiUrl + f"&offset={tempLimit}")
27-
time.sleep(3)
16+
onlineModels = requests.get(Constants.cbApiUrl)
17+
time.sleep(3)
18+
try:
2819
results = onlineModels.json()["results"]
2920
count = onlineModels.json()['count']
30-
iterations = iterations + 1
31-
onlineModels.close()
32-
except json.decoder.JSONDecodeError:
33-
print("cb api didn't respond")
21+
iterations = 1
22+
tempLimit = 0
23+
while count > tempLimit and not isOnline:
24+
tempLimit = Constants.cbJsonLimit * iterations
25+
for result in results:
26+
if result['username'] == cbUserName:
27+
isOnline = True
28+
title = result['room_subject']
29+
#thumbUrl = result['image_url'] + "?" + str(int(time.time()))
30+
break
31+
onlineModels = requests.get(Constants.cbApiUrl + f"&offset={tempLimit}")
32+
time.sleep(3)
33+
results = onlineModels.json()["results"]
34+
count = onlineModels.json()['count']
35+
iterations = iterations + 1
36+
except json.decoder.JSONDecodeError:
37+
logger.warning("cb api didn't respond")
38+
except (requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError):
39+
logger.warning("connection timed out or aborted with Chaturbate. Bot detection or rate limited?")
40+
except requests.exceptions.SSLError:
41+
logger.warning("SSL Error when attempting to connect to Chaturbate")
3442
return isOnline, title, thumbUrl, icon

checkers/Eplay.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
from Constants import Constants
44
from bs4 import BeautifulSoup
55
import json
6+
import logging
7+
8+
logger = logging.getLogger(__name__)
9+
logger.setLevel(Constants.SASSBOT_LOG_LEVEL)
610

711
def isModelOnline(epUserName):
812
isOnline = False
@@ -17,9 +21,10 @@ def isModelOnline(epUserName):
1721
profileJson = json.loads(profileJson[0].text)
1822
isOnline = profileJson["props"]["pageProps"]["dehydratedState"]["queries"][0]["state"]["data"]["live"]
1923
title = profileJson["props"]["pageProps"]["dehydratedState"]["queries"][0]["state"]["data"]["title"]
20-
thumbUrl = profileJson["props"]["pageProps"]["dehydratedState"]["queries"][0]["state"]["data"]["ss"]
24+
thumbUrl = profileJson["props"]["pageProps"]["dehydratedState"]["queries"][0]["state"]["data"]["ss"] + "?" + str(int(time.time()))
2125
icon = profileJson["props"]["pageProps"]["dehydratedState"]["queries"][0]["state"]["data"]["avatar"]
22-
request.close()
2326
except requests.exceptions.ConnectTimeout:
24-
print("connection timed out to eplay.com. Bot detection or rate limited?")
27+
logger.warning("connection timed out to eplay.com. Bot detection or rate limited?")
28+
except requests.exceptions.SSLError:
29+
logger.warning("SSL Error when attempting to connect to Eplay")
2530
return isOnline, title, thumbUrl, icon

checkers/Fansly.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
import nodriver as uc
44
import NoDriverBrowserCreator as ndb
55
import globals
6+
import logging
7+
8+
logger = logging.getLogger(__name__)
9+
logger.setLevel(Constants.SASSBOT_LOG_LEVEL)
610

711
async def isModelOnline(fansUserName):
812
fansUrl = f"https://fansly.com/{fansUserName}"
@@ -25,7 +29,7 @@ async def isModelOnline(fansUserName):
2529
await asyncio.sleep(1*Constants.NODRIVER_WAIT_MULTIPLIER)
2630
globals.browserOpen = False
2731
except Exception as e:
28-
print(f"Error when getting browser for Fansly: {e}")
32+
logger.warning(f"Error when getting browser for Fansly: {e}")
2933
globals.browserOpen = False
3034
return isOnline, title, thumbUrl, icon
3135

@@ -35,7 +39,7 @@ async def ClickEnterButton(page:uc.Tab):
3539
if enterBtn:
3640
await enterBtn.click()
3741
await asyncio.sleep(.5 * Constants.NODRIVER_WAIT_MULTIPLIER)
38-
except :
42+
except asyncio.exceptions.TimeoutError:
3943
pass
4044

4145
async def IsLiveBadge(page:uc.Tab):
@@ -44,7 +48,7 @@ async def IsLiveBadge(page:uc.Tab):
4448
liveBadge = await page.find("live-badge bold font-size-sm", best_match=True)
4549
if liveBadge:
4650
live = True
47-
except :
51+
except asyncio.exceptions.TimeoutError:
4852
pass
4953
return live
5054

@@ -57,6 +61,6 @@ async def GetIcon(page:uc.Tab):
5761
iconElement = await page.find("image-overlay-flex", best_match=True)
5862
await iconElement.save_screenshot( "images/fansIcon.jpg")
5963
icon = "images/fansIcon.jpg"
60-
except:
64+
except asyncio.exceptions.TimeoutError:
6165
pass
6266
return icon

0 commit comments

Comments
 (0)