add basic support for blossom uploads

This commit is contained in:
dbth 2025-01-02 15:28:20 +01:00
parent 20ae96335a
commit 2033a1f721
2 changed files with 93 additions and 0 deletions

3
.gitignore vendored
View File

@ -193,3 +193,6 @@ tests/pagerank/network_graph_99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f
tests/test_data/wallet_mint_api/wallet.sqlite3
.env_bkp2
/ui/noogle/dev-dist
tests/cat4.png
tests/cat4.png
*.png

View File

@ -0,0 +1,90 @@
import base64
import hashlib
import json
import mimetypes
import os
import aiohttp
from nostr_sdk import Keys, Tag, EventBuilder, Kind, Timestamp
def sha256(file):
h = hashlib.sha256()
h.update(file)
return h.digest().hex()
async def check(url, sha256, key):
async with aiohttp.ClientSession(url) as sess:
b64_auth = await generate_blossom_header(key, sha256, "get")
headers = {
"Authorization": b64_auth
}
async with sess.get(f"{sha256}", headers=headers) as resp:
return resp.status == 200
async def generate_blossom_header(key, hash, method):
keys = Keys.parse(key)
t_tag = Tag.parse(["t", method])
x_tag = Tag.parse(["x", hash])
expiration_tag = Tag.parse(["expiration", str(Timestamp.now().as_secs() + 300)])
tags = [x_tag, t_tag, expiration_tag]
eb = EventBuilder(Kind(24242), "Uploading blob with SHA-256 hash").tags(tags)
event = eb.sign_with_keys(keys)
encoded_nip98_event = base64.b64encode(event.as_json().encode('utf-8')).decode('utf-8')
return "Nostr " + encoded_nip98_event
def upload_image_to_blossom(file_path, url):
"""Uploads an image to a Blossom server via a PUT request."""
async def upload_blossom(filepath, pkey, url):
with open(filepath, "rb") as f:
mtime = int(os.fstat(f.fileno()).st_mtime)
file = f.read()
hash = sha256(file)
b64_auth = await generate_blossom_header(pkey, hash, "upload")
file_stats = os.stat(filepath)
sizeinmb = file_stats.st_size / (1024 * 1024)
print("Filesize of Uploaded media: " + str(sizeinmb) + " Mb.")
if await check(url, hash, pkey):
print(f"Blob {hash} is up to date for [{filepath}].")
else:
print(f"Storing file [{hash}] on blossom.")
content_type = mimetypes.guess_type(filepath)[0] or 'application/octet-stream'
# Upload object to blossom.
async with aiohttp.ClientSession() as sess:
async with sess.put(
url = url.rstrip('/') + '/upload',
data=file,
headers={
"Authorization": b64_auth,
"Content-Type": content_type
}) as resp:
if resp.status == 413:
print("Can't upload on Blossom Server")
return "Can't upload on Blossom Server"
elif resp.status != 200:
txt = await resp.text()
print(txt)
else:
res = await resp.text()
resjson = json.loads(res)
print(resjson["url"])
return resjson["url"]