forked from tgstation/tgstation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
populate_key_2018-07-09.py
92 lines (90 loc) · 4.59 KB
/
populate_key_2018-07-09.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
#Python 3+ Script for populating the key of all ckeys in player table made by Jordie0608
#
#Before starting ensure you have installed the mysqlclient package https://github.com/PyMySQL/mysqlclient-python
#It can be downloaded from command line with pip:
#pip install mysqlclient
#And that you have run the most recent commands listed in database_changelog.txt
#
#To view the parameters for this script, execute it with the argument --help
#All the positional arguments are required, remember to include a prefixe in your table name if you use one
#--useckey and --onlynull are optional arguments, see --help for their function
#An example of the command used to execute this script from powershell:
#python populate_key_2018-07-09.py "localhost" "root" "password" "feedback" "SS13_player" --onlynull --useckey
#
#This script requires an internet connection to function
#Sometimes byond.com fails to return the page for a valid ckey, this can be a temporary problem and may be resolved by rerunning the script
#You can have the script use the existing ckey instead if the key is unable to be parsed with the --useckey optional argument
#To make the script only iterate on rows that failed to parse a ckey and have a null byond_key column, use the --onlynull optional argument
#To make the script only iterate on rows that have a matching ckey and byond_key column, use the --onlyckeymatch optional argument
#The --onlynull and --onlyckeymatch arguments are mutually exclusive, the script can't be run with both of them enabled
#
#It's safe to run this script with your game server(s) active.
import MySQLdb
import argparse
import re
import sys
from urllib.request import urlopen
from datetime import datetime
if sys.version_info[0] < 3:
raise Exception("Python must be at least version 3 for this script.")
query_values = ""
current_round = 0
parser = argparse.ArgumentParser()
parser.add_argument("address", help="MySQL server address (use localhost for the current computer)")
parser.add_argument("username", help="MySQL login username")
parser.add_argument("password", help="MySQL login password")
parser.add_argument("database", help="Database name")
parser.add_argument("playertable", help="Name of the player table (remember a prefix if you use one)")
parser.add_argument("--useckey", help="Use the player's ckey for their key if unable to contact or parse their member page", action="store_true")
group = parser.add_mutually_exclusive_group()
group.add_argument("--onlynull", help="Only try to update rows if their byond_key column is null, mutually exclusive with --onlyckeymatch", action="store_true")
group.add_argument("--onlyckeymatch", help="Only try to update rows that have matching ckey and byond_key columns from the --useckey argument, mutually exclusive with --onlynull", action="store_true")
args = parser.parse_args()
where = ""
if args.onlynull:
where = " WHERE byond_key IS NULL"
if args.onlyckeymatch:
where = " WHERE byond_key = ckey"
db=MySQLdb.connect(host=args.address, user=args.username, passwd=args.password, db=args.database)
cursor=db.cursor()
player_table = args.playertable
cursor.execute("SELECT ckey FROM {0}{1}".format(player_table, where))
ckey_list = cursor.fetchall()
failed_ckeys = []
start_time = datetime.now()
success = 0
fail = 0
print("Beginning script at {0}".format(start_time.strftime("%Y-%m-%d %H:%M:%S")))
if not ckey_list:
print("Query returned no rows")
for current_ckey in ckey_list:
link = urlopen("https://secure.byond.com/members/{0}/?format=text".format(current_ckey[0]))
data = link.read()
data = data.decode("ISO-8859-1")
match = re.search("\tkey = \"(.+)\"", data)
if match:
key = match.group(1)
success += 1
else:
fail += 1
failed_ckeys.append(current_ckey[0])
msg = "Failed to parse a key for {0}".format(current_ckey[0])
if args.useckey:
msg += ", using their ckey instead"
print(msg)
key = current_ckey[0]
else:
print(msg)
continue
cursor.execute("UPDATE {0} SET byond_key = %s WHERE ckey = %s".format(player_table), (key, current_ckey[0]))
db.commit()
end_time = datetime.now()
print("Script completed at {0} with duration {1}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), end_time - start_time))
if failed_ckeys:
if args.useckey:
print("The following ckeys failed to parse a key so their ckey was used instead:")
else:
print("The following ckeys failed to parse a key and were skipped:")
print("\n".join(failed_ckeys))
print("Keys successfully parsed: {0} Keys failed parsing: {1}".format(success, fail))
cursor.close()