commit 954e66d5238e8218614b57bc2410fe95d7c02b05 Author: Joey Hines Date: Fri May 7 10:17:00 2021 -0500 Initial Commit + Tested and working on a local mcm instance with a small whitelist diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a7e57d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,141 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +.idea/ +whitelist.json \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..032f5af --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Whitelist Importer +A simple python script to import a `whitelist.json` file into MCM. + +## Usage +``` +./whitelist_importer.py [WHITELIST PATH] [MYSQL HOST] [MYSQL USER] [MYSQL PW] [MCM DB Name] +``` \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8ed6025 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +requests==2.25.1 +mysql-connector-python==8.0.24 diff --git a/whitelist_importer.py b/whitelist_importer.py new file mode 100644 index 0000000..a53cb67 --- /dev/null +++ b/whitelist_importer.py @@ -0,0 +1,134 @@ +import json +import requests +import sys +import mysql.connector +import datetime +import time + +from typing import List + +class Application: + def __init__(self, username): + """ + Class containing application data + + :param username: player's username + """ + self.username = username + + def to_insert_query(self): + """ + Created an SQL insert query from the application + + :return: SQL query string + """ + + return """\ + INSERT INTO minecraft_manager_application + (username, age, player_type, ever_banned, read_rules, accepted, date) + VALUES + ("{}", 16, "Imported from Lasagn Whitelist", FALSE, "Yes", TRUE, "{}"); + """.format(self.username, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + + def __str__(self): + return self.username + + +def get_latest_username(uuid: str) -> str: + """ + Gets the latest username of a player from the mojang api + + :param uuid: player's uuid + :return: player name + """ + + r = requests.get("https://api.mojang.com/user/profiles/{}/names".format(uuid)) + + if r.status_code == 200: + j = r.json() + + return j[-1]["name"] + else: + raise Exception("Error getting user {}. Code: {}: {}".format(uuid, r.status_code, r.text)) + + +def parse_whitelist(whitelist_path: str) -> List[Application]: + """ + Process all the applications from the whitelist file + + :return: list of applications + """ + + # Load json from file + with open(whitelist_path, "r") as f: + whitelist = json.load(f) + + # Parse applications from whitelist data + applications = [] + for entry in whitelist: + uuid = entry["uuid"] + + username = get_latest_username(uuid) + + app = Application(username) + + applications.append(app) + + # Prevent Mojang from rate limiting us + time.sleep(0.5) + + return applications + + +def insert_apps_into_db(apps: List[Application], host: str, user: str, pw: str, mcm_db_name: str): + """ + Insert applications into the MCM database + + :param apps: list of applications to import + :param host: mysql host + :param user: mysql user + :param pw: mysql user password + :param mcm_db_name: MCM database name + """ + + # Open database + db = mysql.connector.connect(host=host, user=user, password=pw, database=mcm_db_name) + cursor = db.cursor(buffered=True) + + for app in apps: + # Check if the player already has an application + cursor.execute("SELECT * FROM minecraft_manager_application WHERE username = '{}';".format(app.username)) + + result = cursor.fetchall() + + # If there is not an existing app, insert the application into the DB + if len(result) == 0: + cursor.execute(app.to_insert_query()) + + # Commit and close up + db.commit() + cursor.close() + db.close() + + +def main(): + if len(sys.argv) < 6: + print("{} [WHITELIST PATH] [MYSQL HOST] [MYSQL USER] [MYSQL PW] [MCM DB Name]".format(sys.argv[0])) + quit(0) + else: + # Parse args + whitelist_path = sys.argv[1] + host = sys.argv[2] + user = sys.argv[3] + pw = sys.argv[4] + mc_db_name = sys.argv[5] + + # Parse whitelist + apps = parse_whitelist(whitelist_path) + + # Insert apps into the database + insert_apps_into_db(apps, host, user, pw, mc_db_name) + + +if __name__ == '__main__': + main()