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))