0.2.0 Package release

This commit is contained in:
Victor Westerlund 2020-11-30 04:09:28 +01:00
parent 32125223d4
commit 8b814546fe
8 changed files with 347 additions and 62 deletions

View file

@ -2,15 +2,11 @@ import requests
import hashlib import hashlib
import time import time
class RequestError(Exception): pass
class Texture: class Texture:
endpoint = "https://www.labymod.net/page/php/cape.php" endpoint = "https://www.labymod.net/page/php/cape.php"
def __init__(self,cookie,img): def __init__(self,cookie):
self.validate(cookie,img)
self.body = b"" # Initialize request body self.body = b"" # Initialize request body
self.cookies = dict(PHPSESSID = cookie) self.cookies = dict(PHPSESSID = cookie)
self.boundary = self.boundary() self.boundary = self.boundary()
@ -33,13 +29,9 @@ class Texture:
} }
self.appendBinaryFormData(b"cosmetic",b"cape") 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 # Generate boundary header from MD5-hash of current time
def boundary(self): def boundary(self):
seed = str(time.time()) seed = str(time.time())
@ -83,7 +75,9 @@ class Texture:
# ----------------------------------- # -----------------------------------
def update(self): def update(self,img):
self.appendBinaryFormData(b"file",self.bOpen(img))
self.closeBinaryFormData() # Add final boundary header self.closeBinaryFormData() # Add final boundary header
request = requests.post(Texture.endpoint, request = requests.post(Texture.endpoint,
@ -93,6 +87,157 @@ class Texture:
) )
# Raise exception if request fails # Raise exception if request fails
# Use [3:5] to clean up junk chars from reponse body request.raise_for_status()
if(str(request.text)[3:5] != "OK"):
raise RequestError(str(request.text)) class Template:
endpoint = "https://www.labymod.net/page/php/setCapeTpl.php"
templates = {
"labymod": "10_LABYMOD.png",
"minecon2011": "30_MINECON2011.png",
"minecon2012": "30_MINECON2012.png",
"minecon2013": "30_MINECON2013.png",
"minecon2015": "30_MINECON2015.png",
"minecon2016": "30_MINECON2016.png",
"minecon2019": "30_MINECON2019.png",
"prismarine": "30_PRISMARINE.png",
"christmas2010": "40_CHRISTMAS2010.png",
"cobalt": "40_COBALT.png",
"julianclark": "40_JULIANCLARK.png",
"mapmaker": "40_MAPMAKER.png",
"mojira": "40_MOJIRA.png",
"mrmessiah": "40_MRMESSIAH.png",
"newyear": "40_NEWYEAR.png",
"scrolls": "40_SCROLLS.png",
"translator": "40_TRANSLATOR.png",
"turtle": "40_TURTLE.png",
"winner": "40_WINNER.png"
}
def __init__(self,cookie):
self.cookies = dict(PHPSESSID = cookie)
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": "application/x-www-form-urlencoded; charset=UTF-8"
}
self.body = ""
# Payload
self.addEncodedFormData("cosmetic","cape")
# -----------------------------------
# Add URLEncoded form data (x-www-form-urlencoded)
def addEncodedFormData(self,key,value):
body = "&"
# Remove '&' delimiter for first item
if(self.body == ""):
body = ""
body += f"{key}={value}"
self.body += body
# -----------------------------------
def update(self,value):
value = value.lower()
if(value not in Template.templates):
raise ValueError(f"'{value}' is not a valid template.")
texture = Template.templates[value]
self.addEncodedFormData("cape",texture)
request = requests.post(Template.endpoint,
headers = self.headers,
cookies = self.cookies,
data = self.body
)
# Raise exception if request fails
request.raise_for_status()
class Visibility:
endpoint = "https://www.labymod.net/api/change"
def __init__(self,cookie):
self.cookies = dict(PHPSESSID = cookie)
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": "application/x-www-form-urlencoded; charset=UTF-8"
}
self.body = ""
# Payload
self.addEncodedFormData("type","switch")
self.addEncodedFormData("item",459595)
self.addEncodedFormData("site","control")
# -----------------------------------
# Add URLEncoded form data (x-www-form-urlencoded)
def addEncodedFormData(self,key,value):
body = "&"
# Remove '&' delimiter for first item
if(self.body == ""):
body = ""
body += f"{key}={value}"
self.body += body
# -----------------------------------
def update(self,value):
# Interpret strings
if(type(value) != int):
if(value == "show"):
value = 1
elif(value == "hide"):
value = 0
else:
raise ValueError(f"'{value}' is not a valid visibility state.")
self.addEncodedFormData("value",value)
request = requests.post(Visibility.endpoint,
headers = self.headers,
cookies = self.cookies,
data = self.body
)
# Raise exception if request fails
request.raise_for_status()

126
build/lib/labylib/Hat.py Normal file
View file

@ -0,0 +1,126 @@
import requests
class Texture:
endpoint = "https://www.labymod.net/api/change"
def __init__(self,cookie):
self.cookies = dict(PHPSESSID = cookie)
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": "application/x-www-form-urlencoded; charset=UTF-8"
}
self.body = ""
# Payload
self.addEncodedFormData("type","country")
self.addEncodedFormData("item",459594)
self.addEncodedFormData("site","control")
# -----------------------------------
# Add URLEncoded form data (x-www-form-urlencoded)
def addEncodedFormData(self,key,value):
body = "&"
# Remove '&' delimiter for first item
if(self.body == ""):
body = ""
body += f"{key}={value}"
self.body += body
# -----------------------------------
def update(self,value):
self.addEncodedFormData("value",value)
request = requests.post(Texture.endpoint,
headers = self.headers,
cookies = self.cookies,
data = self.body
)
# Raise exception if request fails
request.raise_for_status()
class Visibility:
endpoint = "https://www.labymod.net/api/change"
def __init__(self,cookie):
self.cookies = dict(PHPSESSID = cookie)
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": "application/x-www-form-urlencoded; charset=UTF-8"
}
self.body = ""
# Payload
self.addEncodedFormData("type","switch")
self.addEncodedFormData("item",459594)
self.addEncodedFormData("site","control")
# -----------------------------------
# Add URLEncoded form data (x-www-form-urlencoded)
def addEncodedFormData(self,key,value):
body = "&"
# Remove '&' delimiter for first item
if(self.body == ""):
body = ""
body += f"{key}={value}"
self.body += body
# -----------------------------------
def update(self,value):
# Interpret strings
if(type(value) != int):
if(value == "show"):
value = 1
else:
value = 0
self.addEncodedFormData("value",value)
request = requests.post(Visibility.endpoint,
headers = self.headers,
cookies = self.cookies,
data = self.body
)
# Raise exception if request fails
request.raise_for_status()

Binary file not shown.

BIN
dist/labylib-0.2.0.tar.gz vendored Normal file

Binary file not shown.

View file

@ -1,7 +1,7 @@
Metadata-Version: 2.1 Metadata-Version: 2.1
Name: labylib Name: labylib
Version: 0.1.0 Version: 0.2.0
Summary: Python API to modify LabyMod cosmetics Summary: API to modify LabyMod cosmetics
Home-page: https://github.com/VictorWesterlund/labylib Home-page: https://github.com/VictorWesterlund/labylib
Author: VicW Author: VicW
Author-email: victor.vesterlund@gmail.com Author-email: victor.vesterlund@gmail.com
@ -23,64 +23,77 @@ Description: ![Labylib](https://storage.googleapis.com/public.victorwesterlund.c
## Installation ## Installation
1. Download and install [Python 3](https://www.python.org/downloads/) for your architecture. 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) 2. Install the latest version of labylib with [`pip3`](https://pypi.org/project/labylib/)
```bash ```bash
$ git clone https://github.com/VictorWesterlund/labylib/ $ python3 -m pip install labylib
$ gh repo clone VictorWesterlund/labylib ```
*..or if that doesn't work*
```python
$ pip3 install labylib
``` ```
## Quickstart ## Quickstart
**1. Import a cosmetics module from `labylib/<cosmetic>`.** 1. Import a labylib Module from the [list of available modules](https://github.com/VictorWesterlund/labylib/wiki/labylib-Modules).
```python3
[A list of all modules and classes can be found here](https://github.com/VictorWesterlund/labylib/wiki/Module-reference-sheet) from labylib import <MODULE>
```python
from labylib import Cape
``` ```
**2. Initialize a module class.** 2. Each Module comes with a set of classes available to each cosmetic. Pick a class for your Module. (`Visibility`,`Texture` etc.)
3. Initialize the class by passing it a `PHPSESSID`<br>
All labylib classes take a `PHPSESSID` as their first argument. [**Here's what it is and where to find it**](https://github.com/VictorWesterlund/labylib/wiki/Find-your-PHPSESSID)
```python3
_Example with `Cape` where a file-path is expected as a second argument:_ # Example
```python cape_vis = Cape.Visibility(PHPSESSID)
texture = Cape.Texture("<String PHPSESSID>","<String PATH_TO_PNG>") # labylib = Cape.Texture("772nnas663jkc8ahbb2","/home/VicW/coolCape-2.png") ```
4. Call `update()` with a value expected by the class. Just like Modules, the value expected depends on the class.
```python3
# Example
cape_vis.update("show")
``` ```
**3. Submit a cosmetic update** # Advanced Usage
```python ## Request headers, cookies and body
texture.update() Each class instance can be modified before `update()` is called to make changes to the request headers, cookies etc. You can even add additional encoded form data to the request body if necessary.
```
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. labylib uses [`Requests`](https://requests.readthedocs.io/en/master/) under the hood and request parameters like headers and cookies can be modified in accordance with `Request`'s conventions.
```python ```python3
try: # This will send add a "foo=bar" cookie and header with the request
texture.update() cape_vis.cookies["foo"] = "bar"
except RequestError as error: cape_vis.headers["foo"] = "bar"
print("Caugh RequestError exception:" + error)
# "Caugh RequestError exception: Session expired." cape_vis.update("show")
``` ```
## Advanced usage ### To append form data to the request body of an instance:
### 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("<String PHPSESSID>","<String PATH_TO_PNG>")
texture.headers["Origin"] = "https://example.com/" **For `x-www-form-urlencoded` requests:** Append form data with the `addEncodedFormData(key,value)` method:
texture.cookies["Foo"] = "Bar" ```python3
# This will add "foo=bar" to the URL encoded payload
labylib.update() cape_vis.addEncodedFormData("foo","bar")
cape_vis.update("show")
``` ```
### HTTP POST Body
Binary form-data can be appended by calling `self.appendBinaryFormData(name,payload)`.
```python
texture = Cape.Texture("<String PHPSESSID>","<String PATH_TO_PNG>")
texture.appendBinaryFormData(b"foo",b"bar") **For `multipart/form-data` requests:** Append binary form data with the `addBinaryFormData(key,payload)` method:
texture.appendBinaryFormData(b"file","/home/VicW/home/VicW/coolCape-2.png") # Note that 'payload' is a String in this case (as opposed to Binary) ```python3
# This will create a new payload boundary containing "foo=bar"
cape_texture.addBinaryFormData(b"foor",b"bar")
cape_texture.update("show")
``` ```
Special form-data types ('names'): You can also append `image/png` files by passing "file" as the `key` argument. You can either pass binary data directly as a BLOB to `payload` or use `bOpen(<Path_to_PNG>)` to load an image from disk:
|name|Description ```python3
|--|--| # This will create a new payload boundary with a "Content-Type: image/png" header and BLOB body
|`'file'`| Submit cosmetic texture file as BLOB by passing `payload` a binary-encoded PNG.<br>_`self.bOpen()` can be used to 'open()' a file as binary string._ cape_texture.addBinaryFormData(b"file",cape_vis.bOpen("~/someImage.png"))
cape_texture.update("~/myAwesomeTexture.png")
```
## Contribute
If you find any bugs with- or would like to suggest features to labylib, please submit them under [Issues](https://github.com/VictorWesterlund/labylib/issues)
Pull requests to labylib are highly encouraged!
## License
[GNU General Public License v3.0](https://github.com/VictorWesterlund/labylib/blob/master/LICENSE)
Platform: UNKNOWN Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3

View file

@ -1,6 +1,7 @@
README.md README.md
setup.py setup.py
labylib/Cape.py labylib/Cape.py
labylib/Hat.py
labylib/__init__.py labylib/__init__.py
labylib.egg-info/PKG-INFO labylib.egg-info/PKG-INFO
labylib.egg-info/SOURCES.txt labylib.egg-info/SOURCES.txt

View file

@ -5,10 +5,10 @@ with open("README.md","r") as fh:
setuptools.setup( setuptools.setup(
name="labylib", name="labylib",
version="0.1.0", version="0.2.0",
author="VicW", author="VicW",
author_email="victor.vesterlund@gmail.com", author_email="victor.vesterlund@gmail.com",
description="Python API to modify LabyMod cosmetics", description="API to modify LabyMod cosmetics",
long_description=long_description, long_description=long_description,
long_description_content_type="text/markdown", long_description_content_type="text/markdown",
url="https://github.com/VictorWesterlund/labylib", url="https://github.com/VictorWesterlund/labylib",