forked from ppfun/pixelplanet
remove requests dependency from areaDownload.py
This commit is contained in:
parent
ed154a0737
commit
d79636ae88
|
@ -30,6 +30,7 @@ Script to move canvas chunks, i.e. for resizing canvas
|
||||||
downloads an area of the canvas into a png file.
|
downloads an area of the canvas into a png file.
|
||||||
Usage: `areaDownload.py startX_startY endX_endY filename.png`
|
Usage: `areaDownload.py startX_startY endX_endY filename.png`
|
||||||
(note that you can copy the current coordinates in this format on the site by pressing R)
|
(note that you can copy the current coordinates in this format on the site by pressing R)
|
||||||
|
**Requires:** aiohttp, asyncio and PIL python3 packages
|
||||||
|
|
||||||
## historyDownload.py
|
## historyDownload.py
|
||||||
downloads the history from an canvas area between two dates.
|
downloads the history from an canvas area between two dates.
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import PIL.Image
|
import PIL.Image
|
||||||
import sys, os, io
|
import sys, os, io, math
|
||||||
import asyncio
|
import asyncio
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import requests
|
|
||||||
import math
|
|
||||||
|
|
||||||
apime = requests.get('https://pixelplanet.fun/api/me').json()
|
USER_AGENT = "ppfun areaDownload 1.0"
|
||||||
|
PPFUN_URL = "https://pixelplanet.fun"
|
||||||
|
|
||||||
class Color(object):
|
class Color(object):
|
||||||
def __init__(self, index, rgb):
|
def __init__(self, index, rgb):
|
||||||
|
@ -18,8 +17,8 @@ class EnumColorPixelplanet:
|
||||||
|
|
||||||
ENUM = []
|
ENUM = []
|
||||||
|
|
||||||
def getColors(canvasid):
|
def getColors(canvas):
|
||||||
colors = apime['canvases'][canvasid]['colors']
|
colors = canvas['colors']
|
||||||
for i, color in enumerate(colors):
|
for i, color in enumerate(colors):
|
||||||
EnumColorPixelplanet.ENUM.append(Color(i, tuple(color)))
|
EnumColorPixelplanet.ENUM.append(Color(i, tuple(color)))
|
||||||
|
|
||||||
|
@ -82,12 +81,36 @@ class Matrix:
|
||||||
self.matrix[x] = {}
|
self.matrix[x] = {}
|
||||||
self.matrix[x][y] = color
|
self.matrix[x][y] = color
|
||||||
|
|
||||||
|
async def fetchMe():
|
||||||
|
url = f"{PPFUN_URL}/api/me"
|
||||||
|
headers = {
|
||||||
|
'User-Agent': USER_AGENT
|
||||||
|
}
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
attempts = 0
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
async with session.get(url, headers=headers) as resp:
|
||||||
|
data = await resp.json()
|
||||||
|
return data
|
||||||
|
except:
|
||||||
|
if attempts > 3:
|
||||||
|
print(f"Could not get {url} in three tries, cancelling")
|
||||||
|
raise
|
||||||
|
attempts += 1
|
||||||
|
print(f"Failed to load {url}, trying again in 5s")
|
||||||
|
await asyncio.sleep(5)
|
||||||
|
pass
|
||||||
|
|
||||||
async def fetch(session, canvasID, canvasoffset, ix, iy, target_matrix):
|
async def fetch(session, canvasID, canvasoffset, ix, iy, target_matrix):
|
||||||
url = f'https://pixelplanet.fun/chunks/{canvasID}/{ix}/{iy}.bmp'
|
url = f"{PPFUN_URL}/chunks/{canvasID}/{ix}/{iy}.bmp"
|
||||||
|
headers = {
|
||||||
|
'User-Agent': USER_AGENT
|
||||||
|
}
|
||||||
attempts = 0
|
attempts = 0
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
async with session.get(url) as resp:
|
async with session.get(url, headers=headers) as resp:
|
||||||
data = await resp.read()
|
data = await resp.read()
|
||||||
offset = int(-canvasoffset * canvasoffset / 2)
|
offset = int(-canvasoffset * canvasoffset / 2)
|
||||||
off_x = ix * 256 + offset
|
off_x = ix * 256 + offset
|
||||||
|
@ -110,14 +133,17 @@ async def fetch(session, canvasID, canvasoffset, ix, iy, target_matrix):
|
||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
if attempts > 3:
|
if attempts > 3:
|
||||||
|
print(f"Could not get {url} in three tries, cancelling")
|
||||||
raise
|
raise
|
||||||
attempts += 1
|
attempts += 1
|
||||||
|
print(f"Failed to load {url}, trying again in 3s")
|
||||||
|
await asyncio.sleep(3)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def get_area(canvasID, x, y, w, h):
|
async def get_area(canvasID, canvas, x, y, w, h):
|
||||||
target_matrix = Matrix()
|
target_matrix = Matrix()
|
||||||
target_matrix.add_coords(x, y, w, h)
|
target_matrix.add_coords(x, y, w, h)
|
||||||
canvasoffset = math.pow(apime["canvases"][f"{canvasID}"]["size"], 0.5)
|
canvasoffset = math.pow(canvas['size'], 0.5)
|
||||||
offset = int(-canvasoffset * canvasoffset / 2)
|
offset = int(-canvasoffset * canvasoffset / 2)
|
||||||
xc = (x - offset) // 256
|
xc = (x - offset) // 256
|
||||||
wc = (x + w - offset) // 256
|
wc = (x + w - offset) // 256
|
||||||
|
@ -134,30 +160,30 @@ async def get_area(canvasID, x, y, w, h):
|
||||||
|
|
||||||
def validateCoorRange(ulcoor: str, brcoor: str, canvasSize: int): # stolen from hf with love
|
def validateCoorRange(ulcoor: str, brcoor: str, canvasSize: int): # stolen from hf with love
|
||||||
if not ulcoor or not brcoor:
|
if not ulcoor or not brcoor:
|
||||||
return 'Not all coordinates defined'
|
return "Not all coordinates defined"
|
||||||
splitCoords = ulcoor.strip().split('_')
|
splitCoords = ulcoor.strip().split('_')
|
||||||
if not len(splitCoords) == 2:
|
if not len(splitCoords) == 2:
|
||||||
return 'Invalid Coordinate Format for top-left corner'
|
return "Invalid Coordinate Format for top-left corner"
|
||||||
|
|
||||||
x, y = map(lambda z: int(math.floor(float(z))), splitCoords)
|
x, y = map(lambda z: int(math.floor(float(z))), splitCoords)
|
||||||
|
|
||||||
splitCoords = brcoor.strip().split('_')
|
splitCoords = brcoor.strip().split('_')
|
||||||
if not len(splitCoords) == 2:
|
if not len(splitCoords) == 2:
|
||||||
return 'Invalid Coordinate Format for top-left corner'
|
return "Invalid Coordinate Format for top-left corner"
|
||||||
u, v = map(lambda z: int(math.floor(float(z))), splitCoords)
|
u, v = map(lambda z: int(math.floor(float(z))), splitCoords)
|
||||||
|
|
||||||
error = None
|
error = None
|
||||||
|
|
||||||
if (math.isnan(x)):
|
if (math.isnan(x)):
|
||||||
error = 'x of top-left corner is not a valid number'
|
error = "x of top-left corner is not a valid number"
|
||||||
elif (math.isnan(y)):
|
elif (math.isnan(y)):
|
||||||
error = 'y of top-left corner is not a valid number'
|
error = "y of top-left corner is not a valid number"
|
||||||
elif (math.isnan(u)):
|
elif (math.isnan(u)):
|
||||||
error = 'x of bottom-right corner is not a valid number'
|
error = "x of bottom-right corner is not a valid number"
|
||||||
elif (math.isnan(v)):
|
elif (math.isnan(v)):
|
||||||
error = 'y of bottom-right corner is not a valid number'
|
error = "y of bottom-right corner is not a valid number"
|
||||||
elif (u < x or v < y):
|
elif (u < x or v < y):
|
||||||
error = 'Corner coordinates are aligned wrong'
|
error = "Corner coordinates are aligned wrong"
|
||||||
|
|
||||||
if not error is None:
|
if not error is None:
|
||||||
return error
|
return error
|
||||||
|
@ -166,44 +192,55 @@ def validateCoorRange(ulcoor: str, brcoor: str, canvasSize: int): # stolen from
|
||||||
canvasMinXY = -canvasMaxXY
|
canvasMinXY = -canvasMaxXY
|
||||||
|
|
||||||
if (x < canvasMinXY or y < canvasMinXY or x >= canvasMaxXY or y >= canvasMaxXY):
|
if (x < canvasMinXY or y < canvasMinXY or x >= canvasMaxXY or y >= canvasMaxXY):
|
||||||
return 'Coordinates of top-left corner are outside of canvas'
|
return "Coordinates of top-left corner are outside of canvas"
|
||||||
if (u < canvasMinXY or v < canvasMinXY or u >= canvasMaxXY or v >= canvasMaxXY):
|
if (u < canvasMinXY or v < canvasMinXY or u >= canvasMaxXY or v >= canvasMaxXY):
|
||||||
return 'Coordinates of bottom-right corner are outside of canvas'
|
return "Coordinates of bottom-right corner are outside of canvas"
|
||||||
|
|
||||||
return (x, y, u, v)
|
return (x, y, u, v)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
async def main():
|
||||||
|
apime = await fetchMe()
|
||||||
|
|
||||||
if len(sys.argv) != 5:
|
if len(sys.argv) != 5:
|
||||||
print("Download an area of pixelplanet")
|
print("Download an area of pixelplanet")
|
||||||
print("Usage: areaDownload.py canvasID startX_startY endX_endY filename.png")
|
print("Usage: areaDownload.py canvasID startX_startY endX_endY filename.png")
|
||||||
print("(use R key on pixelplanet to copy coordinates)")
|
print("(use R key on pixelplanet to copy coordinates)")
|
||||||
print("Canvas ID: ", end='')
|
print("canvasID: ", end='')
|
||||||
for canvas in apime['canvases']:
|
for canvasID, canvas in apime['canvases'].items():
|
||||||
if canvas == '2':
|
if 'v' in canvas and canvas['v']:
|
||||||
continue
|
continue
|
||||||
print(f"{canvas} = {apime['canvases'][f'{canvas}']['title']}", end=' ')
|
print(f"{canvasID} = {canvas['title']}", end=', ')
|
||||||
print()
|
print()
|
||||||
|
return
|
||||||
|
|
||||||
|
canvasID = sys.argv[1]
|
||||||
|
|
||||||
|
if canvasID not in apime['canvases']:
|
||||||
|
print("Invalid canvas selected")
|
||||||
|
return
|
||||||
|
|
||||||
|
canvas = apime['canvases'][canvasID]
|
||||||
|
|
||||||
|
if 'v' in canvas and canvas['v']:
|
||||||
|
print("Can\'t get area for 3D canvas")
|
||||||
|
return
|
||||||
|
|
||||||
|
parseCoords = validateCoorRange(sys.argv[2], sys.argv[3], canvas['size'])
|
||||||
|
|
||||||
|
if (type(parseCoords) is str):
|
||||||
|
print(parseCoords)
|
||||||
|
sys.exit()
|
||||||
else:
|
else:
|
||||||
canvasID = sys.argv[1]
|
x, y, w, h = parseCoords
|
||||||
|
w = w - x + 1
|
||||||
|
h = h - y + 1
|
||||||
|
|
||||||
if canvasID == '2':
|
EnumColorPixelplanet.getColors(canvas)
|
||||||
print('Can\'t get area for 3D canvas')
|
filename = sys.argv[4]
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
parseCoords = validateCoorRange(sys.argv[2], sys.argv[3], apime["canvases"][f"{canvasID}"]["size"])
|
matrix = await get_area(canvasID, canvas, x, y, w, h)
|
||||||
|
matrix.create_image(filename)
|
||||||
|
print("Done!")
|
||||||
|
|
||||||
if (type(parseCoords) is str):
|
if __name__ == "__main__":
|
||||||
print(parseCoords)
|
asyncio.run(main())
|
||||||
sys.exit()
|
|
||||||
else:
|
|
||||||
x, y, w, h = parseCoords
|
|
||||||
w = w - x + 1
|
|
||||||
h = h - y + 1
|
|
||||||
|
|
||||||
EnumColorPixelplanet.getColors(canvasID)
|
|
||||||
filename = sys.argv[4]
|
|
||||||
|
|
||||||
loop = asyncio.new_event_loop()
|
|
||||||
matrix = loop.run_until_complete(get_area(canvasID, x, y, w, h))
|
|
||||||
matrix.create_image(filename)
|
|
||||||
print("Done!")
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user