SHOW:
|
|
- or go back to the newest paste.
1 | ''' | |
2 | CSGO_STATS_BOT Source Code | |
3 | BETA v0.12 7/29/2014 | |
4 | Created by: Quack Lord | |
5 | ||
6 | How it works: | |
7 | The bot scrapes HLTV.org for certain entries about various players in | |
8 | a post or when summoned with +/u/CSGO_STATS_BOT. It then saves the ID | |
9 | of every post/comment to a text file so it will not comment to the | |
10 | same one twice, preventing spam. Since HLTV.org doesn't neatly create | |
11 | a list of players for me, I had to do it myself with update_Playerlist(). | |
12 | The rest of how it works is explained in comments. | |
13 | ||
14 | I am going to give a brief explanation of what everything does rather | |
15 | than how I do it because I don't have the time to do that. If you have | |
16 | any question on HOW or WHY I did something, pm me @ /u/CSGO_STATS_BOT. | |
17 | ||
18 | Feel free to use/modify this code in anyway you wish except for the | |
19 | reproducing my bot. (i.e I don't want 2 of my bot running around) If | |
20 | you come up with a major change, features, etc that you add to this bot | |
21 | please send me the source code and I will add it in and give you credit | |
22 | where deserved. | |
23 | ''' | |
24 | ||
25 | import sys | |
26 | import time | |
27 | import praw | |
28 | from time import gmtime, strftime | |
29 | import urllib.request | |
30 | from pprint import pprint | |
31 | ||
32 | version = "BETA v0.21" | |
33 | ||
34 | #Creates a list of every player in HLTV.org by going through every ID 1-8410 to | |
35 | #check if the name is not N/A and they have played more than 1 map. If their name | |
36 | #is N/A or they haven't played a map, it adds a line N/A in the text file, otherwise | |
37 | #it adds their name. This will be used later. | |
38 | def update_Playerlist(): | |
39 | i = file_len("PlayerIDs.txt") | |
40 | for b in range (1, 841-int(i/10)): | |
41 | with open("PlayerIDs.txt","a") as f: | |
42 | for c in range (1, 11): | |
43 | i = i+1 | |
44 | url = "http://www.hltv.org/?pageid=173&playerid="+str(i)+"&eventid=0&gameid=2" | |
45 | uf = urllib.request.urlopen(url) | |
46 | text = str(uf.read()) | |
47 | index = text.index("Player stats: ")+14 | |
48 | name = text[index:].split(" ")[0] | |
49 | index = text.index("Maps played")+126 | |
50 | maps = int(text[index:index+1]) | |
51 | if name != "N/A" and maps > 0: | |
52 | f.write(name+"\n") | |
53 | print(str(i)+"- " + name+":"+str(maps)) | |
54 | else: | |
55 | f.write("N/A\n") | |
56 | print(str(i)+"- " +"N/A") | |
57 | ||
58 | #Opens the text file created by update_Playerlist() and adds every name to a list, | |
59 | #the reason I had to have the N/A in the text file was so that here it would keep | |
60 | #the player's ID associated with them. | |
61 | def getPlayers(): | |
62 | players = [] | |
63 | with open("PlayerIDs.txt") as f: | |
64 | for line in f: | |
65 | players.append(line.replace("\n","")) | |
66 | return players | |
67 | ||
68 | #Simply gets the number of lines in a file. | |
69 | def file_len(fname): | |
70 | with open(fname) as f: | |
71 | for i, l in enumerate(f): | |
72 | pass | |
73 | return i + 1 | |
74 | ||
75 | #Modified bubble sort I used to sort the players by ranking. I had to have 3 arrays: | |
76 | #Player names: Stored the name of every player | |
77 | #Player Ratings: Stored the rating of every player | |
78 | #Indexes: created in the sort to keep track of where every player moved to. | |
79 | def bubble_sort(arr1,arr2): | |
80 | indexes = [] | |
81 | for i in range(0, len(arr1)): | |
82 | indexes.append(i) | |
83 | unsorted = True | |
84 | while unsorted: | |
85 | unsorted = False | |
86 | for i in range(1,len(arr1)): | |
87 | if arr2[i] > arr2[i-1]: | |
88 | temp = arr2[i] | |
89 | arr2[i] = arr2[i-1] | |
90 | arr2[i-1] = temp | |
91 | ||
92 | temp = arr1[i] | |
93 | arr1[i] = arr1[i-1] | |
94 | arr1[i-1] = temp | |
95 | ||
96 | temp = indexes[i] | |
97 | indexes[i] = indexes[i-1] | |
98 | indexes[i-1] = temp | |
99 | ||
100 | unsorted = True | |
101 | return indexes | |
102 | ||
103 | #Gets the player infor for every player in list inPost. The data points it gathers | |
104 | #are K/D ratio, Rounds played, Average Kills, Team, HLTV rating, profile URL, Team URL. | |
105 | #I used a VERY crude way of scraping the site for the data I needed. I can't go into | |
106 | #detail without dragging on forever, so PM if you want to know the HOW/WHY behind it. | |
107 | #Then it starts to put together the response with a lot of formatting and the data found. | |
108 | #It calls the bubble_sort method to determine the order of the people in the post. | |
109 | def get_player_info(inPost): | |
110 | Reply = "Player Name | Primary Team | K/D Ratio | Kills per round | More\n"+":----------|:------------|:---------|:---------------|:-----:\n" | |
111 | KDs = [] | |
112 | Rounds = [] | |
113 | AverageKills = [] | |
114 | Team = [] | |
115 | TeamURLs = [] | |
116 | Ratings = [] | |
117 | URLs = [] | |
118 | ||
119 | for i in range (0, len(inPost)): | |
120 | url = "http://www.hltv.org/?pageid=173&playerid="+str(inPost[i].split("|")[0])+"&eventid=0&gameid=2" | |
121 | uf = urllib.request.urlopen(url) | |
122 | text = str(uf.read()) | |
123 | URLs.append(url) | |
124 | ||
125 | index = text.index("K/D Ratio")+124 | |
126 | index2 = text[index:].index("</div>") | |
127 | KDs.append(text[index:index+index2]) | |
128 | ||
129 | index = text.index("Rounds played")+128 | |
130 | index2 = text[index:].index("</div>") | |
131 | Rounds.append(text[index:index+index2]) | |
132 | ||
133 | index = text.index("Average kills per round")+138 | |
134 | index2 = text[index:].index("</div>") | |
135 | AverageKills.append(text[index:index+index2]) | |
136 | ||
137 | index = text.index("Rating <a href")+259 | |
138 | index2 = text[index:].index("</div>") | |
139 | Ratings.append(float(text[index:index+index2])) | |
140 | ||
141 | index = text.index("Primary team:")+129 | |
142 | index = index + text[index:].index(">")+1 | |
143 | index2 = text[index:].index("</a>") | |
144 | Team.append(text[index:index+index2]) | |
145 | ||
146 | index = text.index("Primary team:")+138 | |
147 | index2 = text[index:].index("\"") | |
148 | TeamURLs.append("http://www.hltv.org"+text[index:index+index2].replace("&","&")) | |
149 | ||
150 | ||
151 | if len(inPost) > 0: | |
152 | indexes=bubble_sort(inPost,Ratings) | |
153 | for i in range(0, len(inPost)): | |
154 | # print(str(Ratings[i]) + " " + inPost[i]) | |
155 | Reply = Reply + inPost[i].split("|")[1] + "(["+str(Ratings[i])+"](http://www.hltv.org/?pageid=242)) | [" + Team[indexes[i]] + "]("+TeamURLs[indexes[i]]+") | " + KDs[indexes[i]] + " | " + AverageKills[indexes[i]] + " | [HLTV](" + URLs[indexes[i]] + ")\n" | |
156 | - | Reply = Reply + "^Players ^ordered ^by ^rating ^on ^HLTV.org \n\n\n**DISCLAIMER** *You should not use these stats to solely determine your bet, please do more research before you bet as this bot is not responsible for your bets*\n\n Questions? Comments? Improvements? Let me know [on this bot's thread!](http://www.reddit.com/r/csgobetting/comments/2byr6w/player_stats_bot_for_this_subreddit/)\n \n \n Moderators, Please remove (or message me about) any spam created by this bot (SORRY!) and message me with any bugs you notice, thanks! \n*Current Version: " + version + "* [source](http://pastebin.com/WC52XYeK)" |
156 | + | Reply = Reply + "^Players ^ordered ^by ^rating ^on ^HLTV.org \n\n**NOTE:** *Some players may not appear because I have no stats for them on HLTV, I am looking for more websites to gather data from.*\n\n**DISCLAIMER** *You should not use these stats to solely determine your bet, please do more research before you bet as this bot is not responsible for your bets*\n\n Questions? Comments? Improvements? Let me know [on this bot's thread!](http://www.reddit.com/r/csgobetting/comments/2byr6w/player_stats_bot_for_this_subreddit/)\n \n \n Moderators, Please remove (or message me about) any spam created by this bot (SORRY!) and message me with any bugs you notice, thanks! \n*Current Version: " + version + "* [source](http://pastebin.com/WC52XYeK)" |
157 | ||
158 | return Reply | |
159 | ||
160 | #Stores comment ID to a text file so it doesn't double post. | |
161 | def store_comment_ID(comment): | |
162 | with open("CommentIDs.txt", "a") as f: | |
163 | f.write(comment.id+"\n") | |
164 | ||
165 | #Stores post ID to a text file so it doesn't double post. | |
166 | def store_submission_ID(submission): | |
167 | with open("SubmissionIDs.txt", "a") as f: | |
168 | f.write(submission.id+"\n") | |
169 | ||
170 | #Checks to see if the supplied comment ID has been replied to yet. | |
171 | def check_comment_ID(cid): | |
172 | with open("CommentIDs.txt") as f: | |
173 | for line in f: | |
174 | if cid in line: | |
175 | return False | |
176 | return True | |
177 | ||
178 | #Checks to see if the supplied post ID has been replied to yet. | |
179 | def check_submission_ID(sid): | |
180 | with open("SubmissionIDs.txt") as f: | |
181 | for line in f: | |
182 | if sid in line: | |
183 | return False | |
184 | return True | |
185 | ||
186 | #Main method: | |
187 | #Logs into reddit and gets the newest 20 posts to check through. | |
188 | #First it will check for posts with the flair 'Match' so that it only | |
189 | #goes to matches that haven't been finished yet. It checks the selftext | |
190 | #for names and then saves them to a list and send them up to get_player_info() | |
191 | #Next it goes to comments, searching any of the newest 20 posts for the | |
192 | #+/u/CSGO_STATS_BOT summon. Once it finds the summon, it will search the | |
193 | #same way it does the post. Then both post the replies. | |
194 | ||
195 | #update_Playerlist() | |
196 | r = praw.Reddit('Counter Strike:Global Offensive player stats bot version: ' + version) | |
197 | r.login("USERNAME","PASSWORD") | |
198 | already_done = set() | |
199 | players = getPlayers() | |
200 | print ("Bot logged in...") | |
201 | ||
202 | while True: | |
203 | subreddit = r.get_subreddit('csgobetting') | |
204 | subs = []; | |
205 | subs.append(r.get_submission(submission_id="2byr6w")) | |
206 | for submission in subreddit.get_new(limit=10): | |
207 | subs.append(submission) | |
208 | for submission in subs: | |
209 | ||
210 | inPost = [] | |
211 | #Each Post | |
212 | if submission.link_flair_text == "Match" and check_submission_ID(submission.id): | |
213 | text = submission.selftext.replace(","," ").lower().split() | |
214 | for i in range (0, len(players)): | |
215 | player = players[i].lower() | |
216 | if player in text and players[i] != "N/A" and players[i] not in inPost: | |
217 | print("Found "+players[i]+"(#"+str(i+1)+") in the post!") | |
218 | inPost.append(str(i+1)+"|"+players[i]) | |
219 | try: | |
220 | submission.add_comment(get_player_info(inPost)) | |
221 | store_submission_ID(submission) | |
222 | except: | |
223 | print("Error! not posting(post) " + submission.id) | |
224 | pass | |
225 | ||
226 | #Each comment | |
227 | submission.replace_more_comments(limit=25, threshold=1) | |
228 | flat_comments = praw.helpers.flatten_tree(submission.comments) | |
229 | for comment in flat_comments: | |
230 | inComment = [] | |
231 | text = comment.body.replace(","," ").lower().split() | |
232 | if "+/u/csgo_stats_bot" in text and check_comment_ID(comment.id): | |
233 | for i in range (0, len(players)): | |
234 | player = players[i].lower() | |
235 | if player in text and players[i] != "N/A" and players[i] not in inComment: | |
236 | print("Found "+players[i]+"(#"+str(i+1)+") in a comment!") | |
237 | inComment.append(str(i+1)+"|"+players[i]) | |
238 | if len(inComment) > 0: | |
239 | comment.reply(get_player_info(inComment)) | |
240 | store_comment_ID(comment) | |
241 | print("Sleeping for 1 minutes. Time of sleep: " + strftime("%m-%d-%Y %H:%M:%S")) | |
242 | time.sleep(60) |