Improved logging & single-file executable

This commit is contained in:
Collin Rapp
2020-05-10 20:08:52 -07:00
parent bdbd343f0c
commit b72e7e244b
6 changed files with 43 additions and 16 deletions

1
.gitignore vendored
View File

@@ -6,6 +6,7 @@ __pycache__
build/ build/
dist/ dist/
releases/
*.html *.html
*.out *.out

View File

@@ -3,7 +3,8 @@
## 2020/05/10 ## 2020/05/10
Features: Features:
1. Adding basic initial logging to a file 1. Adding basic initial logging
* Logs both to a file and to the command prompt
Fixes: N/A Fixes: N/A

View File

@@ -1,5 +1,7 @@
@echo off @echo off
set dest=".\dist\"
REM The below is an alternative to using a custom hook for praw REM The below is an alternative to using a custom hook for praw
REM FOR /F "tokens=* USEBACKQ" %%F IN (`pipenv --venv`) DO ( REM FOR /F "tokens=* USEBACKQ" %%F IN (`pipenv --venv`) DO (
REM SET pipenvdir=%%F REM SET pipenvdir=%%F
@@ -12,3 +14,10 @@ pyinstaller ^
--onefile ^ --onefile ^
--additional-hooks-dir .\pyinstaller-hooks\ ^ --additional-hooks-dir .\pyinstaller-hooks\ ^
PointsBot.py PointsBot.py
copy ".\README.md" %dest%
copy ".\LICENSE.md" %dest%
copy ".\CHANGELOG.md" %dest%
mkdir .\releases\
powershell Compress-Archive -Force .\dist\* .\releases\PointsBot_Windows_x64.zip

View File

@@ -2,6 +2,7 @@ import logging
import os import os
import os.path import os.path
import re import re
import sys
import praw import praw
import prawcore import prawcore
@@ -29,7 +30,12 @@ def run():
print_welcome_message() print_welcome_message()
cfg = config.load() cfg = config.load()
logging.basicConfig(filename=cfg.log_path,
file_handler = logging.FileHandler(cfg.log_path, 'w', 'utf-8')
console_handler = logging.StreamHandler(sys.stderr)
console_handler.setLevel(logging.INFO)
# logging.basicConfig(filename=cfg.log_path,
logging.basicConfig(handlers=[file_handler, console_handler],
level=logging.DEBUG, level=logging.DEBUG,
format='%(asctime)s %(levelname)s:%(module)s: %(message)s', format='%(asctime)s %(levelname)s:%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S') datefmt='%Y-%m-%d %H:%M:%S')
@@ -57,16 +63,20 @@ def run():
else: else:
logging.warning('Is NOT moderator for monitored subreddit') logging.warning('Is NOT moderator for monitored subreddit')
monitor_comments(subreddit, db, levels) monitor_comments(subreddit, db, levels, cfg)
# Ignoring other potential exceptions for now, since we may not be able # Ignoring other potential exceptions for now, since we may not be able
# to recover from them as well as from this one # to recover from them as well as from this one
except prawcore.exceptions.RequestException as e: except prawcore.exceptions.RequestException as e:
log.error('Unable to connect; attempting again....') logging.error('Unable to connect to Reddit')
logging.error('Error message: %s', e)
logging.error('Trying again')
except prawcore.exceptions.ServerError as e: except prawcore.exceptions.ServerError as e:
log.error('Lost connection to Reddit; attempting to reconnect....') logging.error('Lost connection to Reddit')
logging.error('Error message: %s', e)
logging.error('Attempting to reconnect')
def monitor_comments(subreddit, db, levels): def monitor_comments(subreddit, db, levels, cfg):
"""Monitor new comments in the subreddit, looking for confirmed solutions.""" """Monitor new comments in the subreddit, looking for confirmed solutions."""
# Passing pause_after=0 will bypass the internal exponential delay, but have # Passing pause_after=0 will bypass the internal exponential delay, but have
# to check if any comments are returned with each query # to check if any comments are returned with each query
@@ -76,7 +86,8 @@ def monitor_comments(subreddit, db, levels):
logging.info('Received comment') logging.info('Received comment')
# TODO more debug info about comment, eg author # TODO more debug info about comment, eg author
logging.debug('Comment text: "%s"', comm.body) logging.debug('Comment author: "%s"', comm.author.name)
# logging.debug('Comment text: "%s"', comm.body)
if not marks_as_solved(comm): if not marks_as_solved(comm):
logging.info('Comment does not mark issue as solved') logging.info('Comment does not mark issue as solved')
@@ -103,17 +114,15 @@ def monitor_comments(subreddit, db, levels):
level_info = level.user_level_info(points, levels) level_info = level.user_level_info(points, levels)
# Reply to the comment marking the submission as solved # Reply to the comment marking the submission as solved
reply_body = reply.make( reply_body = reply.make(solver,
solver, points,
points, level_info,
level_info, feedback_url=cfg.feedback_url,
feedback_url=cfg.feedback_url, scoreboard_url=cfg.scoreboard_url)
scoreboard_url=cfg.scoreboard_url
)
try: try:
comm.reply(reply_body) comm.reply(reply_body)
logging.info('Replied to the comment') logging.info('Replied to the comment')
logging.debug('Reply body: %s', reply_body) # logging.debug('Reply body: %s', reply_body)
except praw.exceptions.APIException as e: except praw.exceptions.APIException as e:
logging.error('Unable to reply to comment: %s', e) logging.error('Unable to reply to comment: %s', e)
db.remove_point(solver) db.remove_point(solver)
@@ -211,7 +220,7 @@ def log_solution_info(comm):
logging.debug('Solution comment:') logging.debug('Solution comment:')
logging.debug('Author: %s', comm.parent().author.name) logging.debug('Author: %s', comm.parent().author.name)
logging.debug('Body: %s', comm.parent().body) logging.debug('Body: %s', comm.parent().body)
logging.debug('"Solved" comment:') logging.debug('Comment marking solution as solved:')
logging.debug('Author: %s', comm.author.name) logging.debug('Author: %s', comm.author.name)
logging.debug('Body: %s', comm.body) logging.debug('Body: %s', comm.body)

View File

@@ -128,6 +128,7 @@ class Config:
def interactive_config(dest): def interactive_config(dest):
configvals = { configvals = {
'core': {}, 'core': {},
'links': {},
'filepaths': {}, 'filepaths': {},
'credentials': {}, 'credentials': {},
'levels': [], 'levels': [],

View File

@@ -12,6 +12,12 @@ EXCESS_POINTS = 100 # TODO move this to level and/or config?
EXCESS_SYMBOL = '\u2605' # A star character EXCESS_SYMBOL = '\u2605' # A star character
EXCESS_SYMBOL_TITLE = 'a star' # Used in comment body EXCESS_SYMBOL_TITLE = 'a star' # Used in comment body
###
# TODO make this a ReplyFactory? pass in feedback & scoreboard URLs to the
# ReplyFactory constructor, then pass in redditor, points, level_info each time
# making a comment, ie probably make `make` or `build` a method of the factory
###
### Main Functions ### ### Main Functions ###