-
Notifications
You must be signed in to change notification settings - Fork 0
/
chessbot.py
160 lines (134 loc) · 5.09 KB
/
chessbot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
from __future__ import print_function
import requests
import socket
import time
from datetime import datetime
import argparse
import tensorflow_chessbot # For neural network model
from helper_functions_chessbot import *
from helper_functions import shortenFEN
from cfb_helpers import * # logging, comment waiting and self-reply helpers
def generateResponseMessage(submission, predictor):
print("\n---\nImage URL: %s" % submission.url)
# Use CNN to make a prediction
fen, certainty, visualize_link = predictor.makePrediction(submission.url)
if fen is None:
print("> %s - Couldn't generate FEN, skipping..." % datetime.now())
print("\n---\n")
return None
fen = shortenFEN(fen) # ex. '111pq11r' -> '3pq2r'
print("Predicted FEN: %s" % fen)
print("Certainty: %.4f%%" % (certainty*100))
# Get side from title or fen
side = getSideToPlay(submission.title, fen)
# Generate response message
msg = generateMessage(fen, certainty, side, visualize_link)
print("fen: %s\nside: %s\n" % (fen, side))
return msg
def processSubmission(submission, cfb, predictor, args, reply_wait_time=10):
# Check if submission passes requirements and wasn't already replied to
if isPotentialChessboardTopic(submission):
if not previouslyRepliedTo(submission, cfb):
# Generate response
response = generateResponseMessage(submission, predictor)
if response is None:
logMessage(submission,"[NO-FEN]") # Skip since couldn't generate FEN
return
# Reply to submission with response
if not args.dry:
logMessage(submission,"[REPLIED]")
submission.reply(response)
else:
logMessage(submission,"[DRY-RUN-REPLIED]")
# Wait after submitting to not overload
waitWithComments(reply_wait_time)
else:
logMessage(submission,"[SKIP]") # Skip since replied to already
else:
logMessage(submission)
time.sleep(1) # Wait a second between normal submissions
def main(args):
resetTensorflowGraph()
running = True
reddit = praw.Reddit('CFB') # client credentials set up in local praw.ini file
cfb = reddit.user.me() # ChessFenBot object
subreddit = reddit.subreddit('chess+chessbeginners+AnarchyChess+betterchess+chesspuzzles')
predictor = tensorflow_chessbot.ChessboardPredictor()
while running:
# Start live stream on all submissions in the subreddit
stream = subreddit.stream.submissions()
try:
for submission in stream:
processSubmission(submission, cfb, predictor, args)
except (socket.error, requests.exceptions.ReadTimeout,
requests.packages.urllib3.exceptions.ReadTimeoutError,
requests.exceptions.ConnectionError) as e:
print(
"> %s - Connection error, skipping and continuing in 30 seconds: %s" % (
datetime.now(), e))
time.sleep(30)
continue
except Exception as e:
print("Unknown Error, skipping and continuing in 30 seconds:",e)
time.sleep(30)
continue
except KeyboardInterrupt:
print("Keyboard Interrupt: Exiting...")
running = False
break
predictor.close()
print('Finished')
def resetTensorflowGraph():
"""WIP needed to restart predictor after an error"""
import tensorflow as tf
print('Reset TF graph')
tf.reset_default_graph() # clear out graph
def runSpecificSubmission(args):
resetTensorflowGraph()
reddit = praw.Reddit('CFB') # client credentials set up in local praw.ini file
cfb = reddit.user.me() # ChessFenBot object
predictor = tensorflow_chessbot.ChessboardPredictor()
submission = reddit.submission(args.sub)
print("URL: ", submission.url)
if submission:
print('Processing...')
processSubmission(submission, cfb, predictor, args)
predictor.close()
print('Done')
def dryRunTest(submission='5tuerh'):
resetTensorflowGraph()
reddit = praw.Reddit('CFB') # client credentials set up in local praw.ini file
predictor = tensorflow_chessbot.ChessboardPredictor()
# Use a specific submission
submission = reddit.submission(submission)
print('Loading %s' % submission.id)
# Check if submission passes requirements and wasn't already replied to
if isPotentialChessboardTopic(submission):
# Generate response
response = generateResponseMessage(submission, predictor)
print("RESPONSE:\n")
print('-----------------------------')
print(response)
print('-----------------------------')
else:
print('Submission not considered chessboard topic')
predictor.close()
print('Finished')
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--dry', help='dry run (don\'t actually submit replies)',
action="store_true", default=False)
parser.add_argument('--test', help='Dry run test on pre-existing comment)',
action="store_true", default=False)
parser.add_argument('--sub', help='Pass submission string to process')
args = parser.parse_args()
if args.test:
print('Doing dry run test on submission')
if args.sub:
dryRunTest(args.sub)
else:
dryRunTest()
elif args.sub is not None:
runSpecificSubmission(args)
else:
main(args)