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