nostrdvm/nostr_dvm/utils/gallery_utils.py
2025-02-01 19:35:39 +01:00

163 lines
5.9 KiB
Python

import asyncio
import hashlib
from datetime import timedelta
from io import BytesIO
from urllib.request import urlopen
import re
import mimetypes
import os
from PIL import Image
import numpy
from nostr_sdk import Keys, EventBuilder, Kind, Client, NostrSigner, Filter, EventId, Tag, PublicKey
from blurhash import encode
import requests
from urllib.parse import urlparse
from nostr_dvm.utils.nostr_utils import send_event, print_send_result
from nostr_dvm.utils.print_utils import bcolors
async def gallery_announce_list(tags, dvm_config, client):
keys = Keys.parse(dvm_config.NIP89.PK)
content = ""
event = EventBuilder(Kind(10011), content).tags(tags).sign_with_keys(keys)
eventid = await send_event(event, client=client, dvm_config=dvm_config)
print(
bcolors.BLUE + "[" + dvm_config.NIP89.NAME + "] Announced Gallery for " + dvm_config.NIP89.NAME + " (EventID: " + str(
eventid.to_hex()) + ")" + bcolors.ENDC)
async def convert_nip93_to_nip68(private_key, relay_list, user_to_import_npub=None, startindex=0):
keys = Keys.parse(private_key)
if user_to_import_npub is None:
user_to_import_npub = keys.public_key().to_hex()
client = Client(NostrSigner.keys(keys))
for relay in relay_list:
await client.add_relay(relay)
await client.connect()
nip93_filter = Filter().kind(Kind(1163)).author(PublicKey.parse(user_to_import_npub))
events = await client.fetch_events(nip93_filter, timedelta(5))
events_vec = events.to_vec()
reversed_events_vec = reversed(events_vec)
counter = -1
for event in reversed_events_vec:
counter += 1
if counter < startindex:
continue
image_url = ""
content = ""
m = ""
x = ""
dim = ""
blurhash = ""
size = ""
for tag in event.tags().to_vec():
if tag.as_vec()[0] == "url":
image_url = tag.as_vec()[1]
elif tag.as_vec()[0] == "m":
m = tag.as_vec()[1]
elif tag.as_vec()[0] == "x":
x = tag.as_vec()[1]
elif tag.as_vec()[0] == "dim":
dim = tag.as_vec()[1]
elif tag.as_vec()[0] == "blurhash":
blurhash = tag.as_vec()[1]
elif tag.as_vec()[0] == "e":
eventid = tag.as_vec()[1]
if len(tag.as_vec()) == 3:
relay_hint = tag.as_vec()[2]
try:
await client.connect_relay(relay_hint)
except Exception as e:
print(relay_hint)
e_filter = Filter().id(EventId.parse(eventid)).limit(1)
content_events = await client.fetch_events(e_filter, timedelta(5))
if len(content_events.to_vec()) > 0:
content_event = content_events.to_vec()[0]
content = re.sub(r'^https?:\/\/.*[\r\n]*', '', content_event.content(), flags=re.MULTILINE).rstrip()
var = input("Convert and post this image? (y(es)/n(o)/d(elete): " + image_url + " Content: " + content + "\n")
if var == "d" or var == "delete":
delete_event = EventBuilder.delete([event.id()]).sign_with_keys(keys)
response_status = await client.send_event(delete_event)
print_send_result(response_status)
elif var == "y" or var == "yes":
try:
response = requests.get(image_url)
img = Image.open(BytesIO(response.content)).convert("RGB")
if blurhash == "":
blurhash = encode(numpy.array(img))
if dim == "":
width, height = img.size
dim = str(width) + "x" + str(height)
if m == "":
m, _ = mimetypes.guess_type(image_url)
if size == "":
try:
d = urlopen(image_url)
size = str(d.info()['Content-Length'])
except Exception:
size = ""
if x == "":
e = BytesIO(response.content)
a = urlparse(image_url)
print(os.path.basename(a.path))
with open(os.path.basename(a.path), "wb") as f:
f.write(e.getbuffer())
h = hashlib.sha256()
with open(os.path.basename(a.path), 'rb') as file:
while True:
# Reading is buffered, so we can read smaller chunks.
chunk = file.read(h.block_size)
if not chunk:
break
h.update(chunk)
x_old = x
x = h.hexdigest()
except Exception as e:
print(e)
print("Image: " + image_url + " Content: " + content + " m: " + m + " x: " + x + " dim: " + dim + " size: " + size + " blurhash: " + blurhash)
imeta_tag = Tag.parse(["imeta", "url " + image_url, "m " + m, "alt " + content, "x " + x, "size " + size, "blurhash " + blurhash ])
x_tag = Tag.parse(["x", x])
alt_tag = Tag.parse(["alt", "List of pictures"])
m_tag = Tag.parse(["m", m])
tags = [alt_tag, imeta_tag, x_tag, m_tag]
nip68event = EventBuilder(Kind(20), content).tags(tags).sign_with_keys(keys)
print(nip68event)
await client.send_event(nip68event)
if __name__ == '__main__':
private_key = "nsec..."
RELAY_LIST = ["wss://relay.primal.net",
"wss://relay.damus.io",
"wss://relay.nostrplebs.com",
"wss://nostr.mom",
"wss://nostr.oxtr.dev",
"wss://relay.nostr.band"
]
startindex = 0
asyncio.run(convert_nip93_to_nip68(private_key, RELAY_LIST, startindex))