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.") |