diff --git a/__init__.py b/__init__.py deleted file mode 100644 index d6beb08..0000000 --- a/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from labylib.labylib import Cape \ No newline at end of file diff --git a/build/lib/labylib/Cape.py b/build/lib/labylib/Cape.py new file mode 100644 index 0000000..fcac83d --- /dev/null +++ b/build/lib/labylib/Cape.py @@ -0,0 +1,98 @@ +import requests +import hashlib +import time + +class RequestError(Exception): pass + +class Texture: + + endpoint = "https://www.labymod.net/page/php/cape.php" + + def __init__(self,cookie,img): + self.validate(cookie,img) + + self.body = b"" # Initialize request body + self.cookies = dict(PHPSESSID = cookie) + self.boundary = self.boundary() + + self.headers = { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br", + "accept-language": "en-US,en;q=0.9,sv;q=0.8", + "cache-control": "no-cache", + "dnt": "1", + "user-agent": "Mozilla/5.0 (Windows NT 5.1; rv:33.0) Gecko/20100101 Firefox/33.0", + "origin": "https://www.labymod.net", + "pragma": "no-cache", + "referer": "https://www.labymod.net/dashboard", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin", + "x-requested-with": "XMLHttpRequest", + "Content-Type": "multipart/form-data; boundary=" + self.boundary + } + + self.appendBinaryFormData(b"cosmetic",b"cape") + self.appendBinaryFormData(b"file",self.bOpen(img)) + + # ----------------------------------- + + def validate(self,cookie,file): + return True + + # Generate boundary header from MD5-hash of current time + def boundary(self): + seed = str(time.time()) + md5 = hashlib.md5(seed.encode("utf-8")) + + boundary = "----WebKitFormBoundary" + md5.hexdigest() + return boundary + + # Open and return file binary as string + def bOpen(self,file): + f = open(file,"rb") + content = f.read() + f.close() + + return content + + # Append form-data to request body and boundary header + def appendBinaryFormData(self,name,payload): + body = contentType = b"" + eol = b"\r\n" + + disposition = b'name="' + name + b'"' + if(name == b"file"): + contentType = b"Content-Type: image/png" + eol + + # Use current epoch as filename. It has to be different from last request + filename = str(round(time.time())) + ".png" + filename = filename.encode() + disposition += b'; filename="' + filename + b'"' + + body += b"--" + self.boundary.encode() + eol # Init data header + body += b"Content-Disposition: form-data; " + disposition + eol + body += contentType + eol + body += payload + eol + + self.body += body + + # Last form-data has been set, add final post width for boundary header + def closeBinaryFormData(self): + self.body += b"--" + self.boundary.encode() + b"--\r\n\r\n" + + # ----------------------------------- + + def update(self): + self.closeBinaryFormData() # Add final boundary header + + request = requests.post(Texture.endpoint, + headers = self.headers, + cookies = self.cookies, + data = self.body + ) + + # Raise exception if request fails + # Use [3:5] to clean up junk chars from reponse body + if(str(request.text)[3:5] != "OK"): + raise RequestError(str(request.text)) \ No newline at end of file diff --git a/build/lib/labylib/__init__.py b/build/lib/labylib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dist/labylib-0.1.0-py3-none-any.whl b/dist/labylib-0.1.0-py3-none-any.whl new file mode 100644 index 0000000..8cfb6c5 Binary files /dev/null and b/dist/labylib-0.1.0-py3-none-any.whl differ diff --git a/dist/labylib-0.1.0.tar.gz b/dist/labylib-0.1.0.tar.gz new file mode 100644 index 0000000..904d2d5 Binary files /dev/null and b/dist/labylib-0.1.0.tar.gz differ diff --git a/labylib.egg-info/PKG-INFO b/labylib.egg-info/PKG-INFO new file mode 100644 index 0000000..39effd8 --- /dev/null +++ b/labylib.egg-info/PKG-INFO @@ -0,0 +1,90 @@ +Metadata-Version: 2.1 +Name: labylib +Version: 0.1.0 +Summary: Python API to modify LabyMod cosmetics +Home-page: https://github.com/VictorWesterlund/labylib +Author: VicW +Author-email: victor.vesterlund@gmail.com +License: UNKNOWN +Description: ![Labylib](https://storage.googleapis.com/public.victorwesterlund.com/github/VictorWesterlund/labylib/labylib.png) + + ### Cosmetics API for Labymod + ![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/VictorWesterlund/labylib?include_prereleases) + ![GitHub last commit](https://img.shields.io/github/last-commit/VictorWesterlund/labylib) + ![Maintenance](https://img.shields.io/maintenance/yes/2021) + + Modify LabyMod cosmetics programmatically with Python. + + |![VicW](https://crafatar.com/renders/body/53c40674-f0a2-4f95-9ce1-479bdd1d8b67?scale=2) | Created by VicW | + |--|--| + + _labylib or Victor Westerlund is in no way sponsored by or affiliated with LabyMod or LabyMedia GmbH._
+ _This program is offered as-is and might stop working at any time_ + + ## Installation + 1. Download and install [Python 3](https://www.python.org/downloads/) for your architecture. + 2. Clone this repo to your machine, or [download a zip](/VictorWesterlund/labylib/archive/master.zip) + ```bash + $ git clone https://github.com/VictorWesterlund/labylib/ + $ gh repo clone VictorWesterlund/labylib + ``` + + ## Quickstart + **1. Import a cosmetics module from `labylib/`.** + + [A list of all modules and classes can be found here](https://github.com/VictorWesterlund/labylib/wiki/Module-reference-sheet) + ```python + from labylib import Cape + ``` + **2. Initialize a module class.** + + All labylib classes take a `PHPSESSID` as their first argument. + + _Example with `Cape` where a file-path is expected as a second argument:_ + ```python + texture = Cape.Texture("","") # labylib = Cape.Texture("772nnas663jkc8ahbb2","/home/VicW/coolCape-2.png") + ``` + + **3. Submit a cosmetic update** + ```python + texture.update() + ``` + Python's [Built-in-exceptions](https://docs.python.org/3/library/exceptions.html#exception-hierarchy) are rasied as needed for missing texture files (`FileNotFoundError`) etc. If a request was sucuessfully sent to the Labymod endpoint, but it returned something falsey (not `OK`). A custom-defined `RequestError` exception will be raised; containing the response received from the endpoint. + ```python + try: + texture.update() + except RequestError as error: + print("Caugh RequestError exception:" + error) + # "Caugh RequestError exception: Session expired." + ``` + + ## Advanced usage + ### HTTP POST Headers + Request headers and cookies can be accessed and modified pre-submission by applying standard list modifications on the followin objects: `self.headers` and `self.cookies` + ```python + texture = Cape.Texture("","") + + texture.headers["Origin"] = "https://example.com/" + texture.cookies["Foo"] = "Bar" + + labylib.update() + ``` + ### HTTP POST Body + Binary form-data can be appended by calling `self.appendBinaryFormData(name,payload)`. + ```python + texture = Cape.Texture("","") + + texture.appendBinaryFormData(b"foo",b"bar") + texture.appendBinaryFormData(b"file","/home/VicW/home/VicW/coolCape-2.png") # Note that 'payload' is a String in this case (as opposed to Binary) + ``` + Special form-data types ('names'): + |name|Description + |--|--| + |`'file'`| Submit cosmetic texture file as BLOB by passing `payload` a binary-encoded PNG.
_`self.bOpen()` can be used to 'open()' a file as binary string._ + +Platform: UNKNOWN +Classifier: Programming Language :: Python :: 3 +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Requires-Python: >=3.6 +Description-Content-Type: text/markdown diff --git a/labylib.egg-info/SOURCES.txt b/labylib.egg-info/SOURCES.txt new file mode 100644 index 0000000..5f90f3a --- /dev/null +++ b/labylib.egg-info/SOURCES.txt @@ -0,0 +1,8 @@ +README.md +setup.py +labylib/Cape.py +labylib/__init__.py +labylib.egg-info/PKG-INFO +labylib.egg-info/SOURCES.txt +labylib.egg-info/dependency_links.txt +labylib.egg-info/top_level.txt \ No newline at end of file diff --git a/labylib.egg-info/dependency_links.txt b/labylib.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/labylib.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/labylib.egg-info/top_level.txt b/labylib.egg-info/top_level.txt new file mode 100644 index 0000000..09c8d44 --- /dev/null +++ b/labylib.egg-info/top_level.txt @@ -0,0 +1 @@ +labylib diff --git a/labylib/__init__.py b/labylib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..27e7eac --- /dev/null +++ b/setup.py @@ -0,0 +1,22 @@ +import setuptools + +with open("README.md","r") as fh: + long_description = fh.read() + +setuptools.setup( + name="labylib", + version="0.1.0", + author="VicW", + author_email="victor.vesterlund@gmail.com", + description="Python API to modify LabyMod cosmetics", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/VictorWesterlund/labylib", + packages=setuptools.find_packages(), + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + ], + python_requires='>=3.6', +) \ No newline at end of file