mirror of
https://github.com/believethehype/nostrdvm.git
synced 2025-09-19 18:21:48 +02:00
auto generate keys/dtagsl auto update user profiles, sdimg2img
This commit is contained in:
38
.env_example
38
.env_example
@@ -1,38 +1,16 @@
|
|||||||
#This is needed for the test_client
|
# Optional LNBITS options to create invoices (if empty, it will use the lud16 from profile)
|
||||||
NOSTR_TEST_CLIENT_PRIVATE_KEY = "a secret hex key for the test dvm client"
|
# Admin Key is (only) required for bot or if any payments should be made
|
||||||
#This is needed for the (optional) bot
|
|
||||||
BOT_PRIVATE_KEY = "The private key for a test bot that communicates with dvms"
|
|
||||||
|
|
||||||
#These are all for the playground and can be replaced and adjusted however needed
|
|
||||||
NOSTR_PRIVATE_KEY = "a secret hexkey for some demo dvms"
|
|
||||||
NOSTR_PRIVATE_KEY2 = "another secret hexkey for demo dvm with another key"
|
|
||||||
NOSTR_PRIVATE_KEY3 = "another secret hexkey for demo dvm with another key"
|
|
||||||
NOSTR_PRIVATE_KEY4 = "another secret hexkey for demo dvm with another key"
|
|
||||||
NOSTR_PRIVATE_KEY5 = "another secret hexkey for demo dvm with another key"
|
|
||||||
|
|
||||||
BOT_PRIVATE_KEY = "The private key for a test bot that communicates with dvms"
|
|
||||||
NOSTR_TEST_CLIENT_PRIVATE_KEY = "a secret hex key for the test dvm client"
|
|
||||||
|
|
||||||
|
|
||||||
# Optional LNBITS options to create invoices (if empty, it will use the lud16 from profile, make sure to set one)
|
|
||||||
LNBITS_INVOICE_KEY = ""
|
LNBITS_INVOICE_KEY = ""
|
||||||
LNBITS_ADMIN_KEY = "" # In order to pay invoices, e.g. from the bot to DVMs, or reimburse users. Keep this secret and use responsibly.
|
LNBITS_ADMIN_KEY = "" # In order to pay invoices, e.g. from the bot to DVMs, or reimburse users. Keep this secret and use responsibly.
|
||||||
LNBITS_HOST = "https://lnbits.com"
|
LNBITS_HOST = "https://lnbits.com"
|
||||||
|
|
||||||
|
#Backend Specific Options for tasks that require them. A DVM needing these should only be started if these are set.
|
||||||
|
|
||||||
# Some d tags we use in the testfile to announce or dvms. Create one at vendata.io)
|
|
||||||
TASK_TEXT_EXTRACTION_NIP89_DTAG = "asdd"
|
|
||||||
TASK_TRANSLATION_NIP89_DTAG = "abcded"
|
|
||||||
TASK_IMAGE_GENERATION_NIP89_DTAG = "fgdfgdf"
|
|
||||||
TASK_IMAGE_GENERATION_NIP89_DTAG2 = "fdgdfg"
|
|
||||||
TASK_IMAGE_GENERATION_NIP89_DTAG3 = "asdasd"
|
|
||||||
TASK_SPEECH_TO_TEXT_NIP89 = "asdasdas"
|
|
||||||
TASK_MEDIA_CONVERTER_NIP89_DTAG = "asdasdasd"
|
|
||||||
TASK_DISCOVER_INACTIVE_NIP89_DTAG = "sdfdfsdf12312"
|
|
||||||
|
|
||||||
|
|
||||||
#Backend Specific Options for tasks that require inputs, such as Endpoints or API Keys
|
|
||||||
OPENAI_API_KEY = "" # Enter your OpenAI API Key to use DVMs with OpenAI services
|
OPENAI_API_KEY = "" # Enter your OpenAI API Key to use DVMs with OpenAI services
|
||||||
LIBRE_TRANSLATE_ENDPOINT = "" # Url to LibreTranslate Endpoint e.g. https://libretranslate.com
|
LIBRE_TRANSLATE_ENDPOINT = "" # Url to LibreTranslate Endpoint e.g. https://libretranslate.com
|
||||||
LIBRE_TRANSLATE_API_KEY = "" # API Key, if required (You can host your own instance where you don't need it)
|
LIBRE_TRANSLATE_API_KEY = "" # API Key, if required (You can host your own instance where you don't need it)
|
||||||
NOVA_SERVER = "" # Enter the address of a nova-server instance, locally or on a machine in your network host:port
|
NOVA_SERVER = "" # Enter the address of a nova-server instance, locally or on a machine in your network host:port
|
||||||
|
|
||||||
|
# We will automatically create dtags and private keys based on the identifier variable in main.
|
||||||
|
# If your DVM already has a dtag and private key you can replace it here before publishing the DTAG to not create a new one.
|
||||||
|
# The name and NIP90 info of the DVM can be changed but the identifier must stay the same in order to not create a different dtag.
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -162,3 +162,4 @@ cython_debug/
|
|||||||
*.db
|
*.db
|
||||||
|
|
||||||
outputs
|
outputs
|
||||||
|
.env2
|
||||||
|
47
main.py
47
main.py
@@ -1,26 +1,24 @@
|
|||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import sys
|
|
||||||
import time
|
import time
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from threading import Thread
|
|
||||||
|
|
||||||
import dotenv
|
import dotenv
|
||||||
from nostr_sdk import Keys
|
|
||||||
|
|
||||||
from bot.bot import Bot
|
from bot.bot import Bot
|
||||||
from playground import build_pdf_extractor, build_googletranslator, build_unstable_diffusion, build_sketcher, \
|
from playground import build_pdf_extractor, build_googletranslator, build_unstable_diffusion, build_sketcher, \
|
||||||
build_dalle, \
|
build_dalle, \
|
||||||
build_whisperx, build_libretranslator, build_external_dvm, build_media_converter, build_inactive_follows_finder
|
build_whisperx, build_libretranslator, build_external_dvm, build_media_converter, build_inactive_follows_finder, \
|
||||||
|
build_image_converter
|
||||||
from utils.definitions import EventDefinitions
|
from utils.definitions import EventDefinitions
|
||||||
from utils.dvmconfig import DVMConfig
|
from utils.dvmconfig import DVMConfig
|
||||||
|
from utils.nostr_utils import check_and_set_private_key
|
||||||
|
|
||||||
|
|
||||||
def run_nostr_dvm_with_local_config():
|
def run_nostr_dvm_with_local_config():
|
||||||
# We will run an optional bot that can communicate with the DVMs
|
# We will run an optional bot that can communicate with the DVMs
|
||||||
# Note this is very basic for now and still under development
|
# Note this is very basic for now and still under development
|
||||||
bot_config = DVMConfig()
|
bot_config = DVMConfig()
|
||||||
bot_config.PRIVATE_KEY = os.getenv("BOT_PRIVATE_KEY")
|
bot_config.PRIVATE_KEY = check_and_set_private_key("bot")
|
||||||
bot_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
bot_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||||
bot_config.LNBITS_ADMIN_KEY = os.getenv("LNBITS_ADMIN_KEY") # The bot will forward zaps for us, use responsibly
|
bot_config.LNBITS_ADMIN_KEY = os.getenv("LNBITS_ADMIN_KEY") # The bot will forward zaps for us, use responsibly
|
||||||
bot_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
bot_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||||
@@ -29,38 +27,46 @@ def run_nostr_dvm_with_local_config():
|
|||||||
# You can add arbitrary DVMs there and instantiate them here
|
# You can add arbitrary DVMs there and instantiate them here
|
||||||
|
|
||||||
# Spawn DVM1 Kind 5000: A local Text Extractor from PDFs
|
# Spawn DVM1 Kind 5000: A local Text Extractor from PDFs
|
||||||
pdfextractor = build_pdf_extractor("PDF Extractor")
|
pdfextractor = build_pdf_extractor("PDF Extractor", "pdf_extractor")
|
||||||
# If we don't add it to the bot, the bot will not provide access to the DVM
|
# If we don't add it to the bot, the bot will not provide access to the DVM
|
||||||
pdfextractor.run()
|
pdfextractor.run()
|
||||||
|
|
||||||
# Spawn DVM2 Kind 5002 Local Text TranslationGoogle, calling the free Google API.
|
# Spawn DVM2 Kind 5002 Local Text TranslationGoogle, calling the free Google API.
|
||||||
translator = build_googletranslator("Google Translator")
|
translator = build_googletranslator("Google Translator", "google_translator")
|
||||||
bot_config.SUPPORTED_DVMS.append(translator) # We add translator to the bot
|
bot_config.SUPPORTED_DVMS.append(translator) # We add translator to the bot
|
||||||
translator.run()
|
translator.run()
|
||||||
|
|
||||||
# Spawn DVM3 Kind 5002 Local Text TranslationLibre, calling the free LibreTranslateApi, as an alternative.
|
# Spawn DVM3 Kind 5002 Local Text TranslationLibre, calling the free LibreTranslateApi, as an alternative.
|
||||||
# This will only run and appear on the bot if an endpoint is set in the .env
|
# This will only run and appear on the bot if an endpoint is set in the .env
|
||||||
if os.getenv("LIBRE_TRANSLATE_ENDPOINT") is not None and os.getenv("LIBRE_TRANSLATE_ENDPOINT") != "":
|
if os.getenv("LIBRE_TRANSLATE_ENDPOINT") is not None and os.getenv("LIBRE_TRANSLATE_ENDPOINT") != "":
|
||||||
libre_translator = build_libretranslator("Libre Translator")
|
libre_translator = build_libretranslator("Libre Translator", "google_translator")
|
||||||
bot_config.SUPPORTED_DVMS.append(libre_translator) # We add translator to the bot
|
bot_config.SUPPORTED_DVMS.append(libre_translator) # We add translator to the bot
|
||||||
libre_translator.run()
|
libre_translator.run()
|
||||||
|
|
||||||
# Spawn DVM3 Kind 5100 Image Generation This one uses a specific backend called nova-server.
|
# Spawn DVM3 Kind 5100 Image Generation This one uses a specific backend called nova-server.
|
||||||
# If you want to use it, see the instructions in backends/nova_server
|
# If you want to use it, see the instructions in backends/nova_server
|
||||||
if os.getenv("NOVA_SERVER") is not None and os.getenv("NOVA_SERVER") != "":
|
if os.getenv("NOVA_SERVER") is not None and os.getenv("NOVA_SERVER") != "":
|
||||||
unstable_artist = build_unstable_diffusion("Unstable Diffusion")
|
unstable_artist = build_unstable_diffusion("Unstable Diffusion", "unstable_diffusion")
|
||||||
bot_config.SUPPORTED_DVMS.append(unstable_artist) # We add unstable Diffusion to the bot
|
bot_config.SUPPORTED_DVMS.append(unstable_artist) # We add unstable Diffusion to the bot
|
||||||
unstable_artist.run()
|
unstable_artist.run()
|
||||||
|
|
||||||
# Spawn DVM4, another Instance of text-to-image, as before but use a different privatekey, model and lora this time.
|
# Spawn DVM4, another Instance of text-to-image, as before but use a different privatekey, model and lora this time.
|
||||||
if os.getenv("NOVA_SERVER") is not None and os.getenv("NOVA_SERVER") != "":
|
if os.getenv("NOVA_SERVER") is not None and os.getenv("NOVA_SERVER") != "":
|
||||||
sketcher = build_sketcher("Sketcher")
|
sketcher = build_sketcher("Sketcher", "sketcher")
|
||||||
bot_config.SUPPORTED_DVMS.append(sketcher) # We also add Sketcher to the bot
|
bot_config.SUPPORTED_DVMS.append(sketcher) # We also add Sketcher to the bot
|
||||||
sketcher.run()
|
sketcher.run()
|
||||||
|
|
||||||
|
# Spawn DVM5, image-to-image, .
|
||||||
|
if os.getenv("NOVA_SERVER") is not None and os.getenv("NOVA_SERVER") != "":
|
||||||
|
imageconverter = build_image_converter("Image Converter Inkpunk", "image_converter_inkpunk")
|
||||||
|
bot_config.SUPPORTED_DVMS.append(imageconverter) # We also add Sketcher to the bot
|
||||||
|
imageconverter.run()
|
||||||
|
|
||||||
|
|
||||||
# Spawn DVM5, Another script on nova-server calling WhisperX to transcribe media files
|
# Spawn DVM5, Another script on nova-server calling WhisperX to transcribe media files
|
||||||
|
|
||||||
if os.getenv("NOVA_SERVER") is not None and os.getenv("NOVA_SERVER") != "":
|
if os.getenv("NOVA_SERVER") is not None and os.getenv("NOVA_SERVER") != "":
|
||||||
whisperer = build_whisperx("Whisperer")
|
whisperer = build_whisperx("Whisperer", "whisperx")
|
||||||
bot_config.SUPPORTED_DVMS.append(whisperer) # We also add Sketcher to the bot
|
bot_config.SUPPORTED_DVMS.append(whisperer) # We also add Sketcher to the bot
|
||||||
whisperer.run()
|
whisperer.run()
|
||||||
|
|
||||||
@@ -68,7 +74,7 @@ def run_nostr_dvm_with_local_config():
|
|||||||
# per call. Make sure you have enough balance and the DVM's cost is set higher than what you pay yourself, except, you know,
|
# per call. Make sure you have enough balance and the DVM's cost is set higher than what you pay yourself, except, you know,
|
||||||
# you're being generous.
|
# you're being generous.
|
||||||
if os.getenv("OPENAI_API_KEY") is not None and os.getenv("OPENAI_API_KEY") != "":
|
if os.getenv("OPENAI_API_KEY") is not None and os.getenv("OPENAI_API_KEY") != "":
|
||||||
dalle = build_dalle("Dall-E 3")
|
dalle = build_dalle("Dall-E 3", "dalle3")
|
||||||
bot_config.SUPPORTED_DVMS.append(dalle)
|
bot_config.SUPPORTED_DVMS.append(dalle)
|
||||||
dalle.run()
|
dalle.run()
|
||||||
|
|
||||||
@@ -82,7 +88,8 @@ def run_nostr_dvm_with_local_config():
|
|||||||
|
|
||||||
tasktiger_external.SUPPORTS_ENCRYPTION = False # if the dvm does not support encrypted events, just send a regular event and mark it with p tag. Other dvms might initial answer
|
tasktiger_external.SUPPORTS_ENCRYPTION = False # if the dvm does not support encrypted events, just send a regular event and mark it with p tag. Other dvms might initial answer
|
||||||
bot_config.SUPPORTED_DVMS.append(tasktiger_external)
|
bot_config.SUPPORTED_DVMS.append(tasktiger_external)
|
||||||
# Don't run it, it's on someone else's machine and we simply make the bot aware of it.
|
# Don't run it, it's on someone else's machine, and we simply make the bot aware of it.
|
||||||
|
|
||||||
|
|
||||||
# DVM: 8 Another external dvm for recommendations:
|
# DVM: 8 Another external dvm for recommendations:
|
||||||
ymhm_external = build_external_dvm(name="External DVM: You might have missed",
|
ymhm_external = build_external_dvm(name="External DVM: You might have missed",
|
||||||
@@ -95,16 +102,18 @@ def run_nostr_dvm_with_local_config():
|
|||||||
bot_config.SUPPORTED_DVMS.append(ymhm_external)
|
bot_config.SUPPORTED_DVMS.append(ymhm_external)
|
||||||
|
|
||||||
# Spawn DVM9.. A Media Grabber/Converter
|
# Spawn DVM9.. A Media Grabber/Converter
|
||||||
media_bringer = build_media_converter("Media Bringer")
|
media_bringer = build_media_converter("Media Bringer", "media_converter")
|
||||||
bot_config.SUPPORTED_DVMS.append(media_bringer) # We also add Sketcher to the bot
|
bot_config.SUPPORTED_DVMS.append(media_bringer)
|
||||||
media_bringer.run()
|
media_bringer.run()
|
||||||
|
|
||||||
#Spawn DVM10 Discover inactive followers
|
# Spawn DVM10 Discover inactive followers
|
||||||
discover_inactive = build_inactive_follows_finder("Bygones")
|
discover_inactive = build_inactive_follows_finder("Bygones", "discovery_inactive_follows")
|
||||||
bot_config.SUPPORTED_DVMS.append(discover_inactive) # We also add Sketcher to the bot
|
bot_config.SUPPORTED_DVMS.append(discover_inactive)
|
||||||
discover_inactive.run()
|
discover_inactive.run()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Bot(bot_config)
|
Bot(bot_config)
|
||||||
|
|
||||||
# Keep the main function alive for libraries that require it, like openai
|
# Keep the main function alive for libraries that require it, like openai
|
||||||
|
157
playground.py
157
playground.py
@@ -1,37 +1,36 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from nostr_sdk import PublicKey, Keys
|
from nostr_sdk import PublicKey
|
||||||
|
|
||||||
from interfaces.dvmtaskinterface import DVMTaskInterface
|
from interfaces.dvmtaskinterface import DVMTaskInterface
|
||||||
from tasks.convert_media import MediaConverter
|
from tasks.convert_media import MediaConverter
|
||||||
from tasks.discovery_inactive_follows import DiscoverInactiveFollows
|
from tasks.discovery_inactive_follows import DiscoverInactiveFollows
|
||||||
from tasks.imagegeneration_openai_dalle import ImageGenerationDALLE
|
from tasks.imagegeneration_openai_dalle import ImageGenerationDALLE
|
||||||
from tasks.imagegeneration_sdxl import ImageGenerationSDXL
|
from tasks.imagegeneration_sdxl import ImageGenerationSDXL
|
||||||
|
from tasks.imagegeneration_sdxlimg2img import ImageGenerationSDXLIMG2IMG
|
||||||
from tasks.textextraction_whisperx import SpeechToTextWhisperX
|
from tasks.textextraction_whisperx import SpeechToTextWhisperX
|
||||||
from tasks.textextraction_pdf import TextExtractionPDF
|
from tasks.textextraction_pdf import TextExtractionPDF
|
||||||
from tasks.translation_google import TranslationGoogle
|
from tasks.translation_google import TranslationGoogle
|
||||||
from tasks.translation_libretranslate import TranslationLibre
|
from tasks.translation_libretranslate import TranslationLibre
|
||||||
from utils.admin_utils import AdminConfig
|
from utils.admin_utils import AdminConfig
|
||||||
from utils.definitions import EventDefinitions
|
|
||||||
from utils.dvmconfig import DVMConfig
|
from utils.dvmconfig import DVMConfig
|
||||||
from utils.nip89_utils import NIP89Config, nip89_create_d_tag
|
from utils.nip89_utils import NIP89Config, check_and_set_d_tag
|
||||||
|
from utils.nostr_utils import check_and_set_private_key
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This File is a playground to create DVMs. It shows some examples of DVMs that make use of the modules in the tasks folder
|
This File is a playground to create DVMs. It shows some examples of DVMs that make use of the modules in the tasks folder
|
||||||
These DVMs should be considered examples and will be extended in the future. env variables are used to not commit keys,
|
These DVMs should be considered examples and will be extended in the future.
|
||||||
but if used privatley, these can also be directly filled in this file. The main.py function calls some of the functions
|
Keys and dtags will be automatically generated and stored in the .env file.
|
||||||
defined here and starts the DVMs.
|
If you already have a pk and dtag you can replace them there before publishing the nip89
|
||||||
|
|
||||||
|
|
||||||
Note that the admin_config is optional, and if given commands as defined in admin_utils will be called at start of the
|
Note that the admin_config is optional, and if given commands as defined in admin_utils will be called at start of the
|
||||||
DVM. For example the NIP89 event can be rebroadcasted (store the d_tag somewhere).
|
DVM. For example the NIP89 event can be rebroadcasted.
|
||||||
|
|
||||||
DM_ALLOWED is used to tell the DVM to which npubs it should listen to. We use this here to listen to our bot,
|
If LNBITS_INVOICE_KEY is not set (=""), the DVM is still zappable but a lud16 address in required in the profile.
|
||||||
as defined in main.py to perform jobs on it's behalf and reply.
|
|
||||||
|
|
||||||
if LNBITS_INVOICE_KEY is not set (=""), the DVM is still zappable but a lud16 address in required in the profile.
|
Additional options can be set, for example to preinitalize vaiables or give parameters that are required to perform a
|
||||||
|
|
||||||
additional options can be set, for example to preinitalize vaiables or give parameters that are required to perform a
|
|
||||||
task, for example an address or an API key.
|
task, for example an address or an API key.
|
||||||
|
|
||||||
|
|
||||||
@@ -39,17 +38,28 @@ task, for example an address or an API key.
|
|||||||
|
|
||||||
# Generate an optional Admin Config, in this case, whenever we give our DVMs this config, they will (re)broadcast
|
# Generate an optional Admin Config, in this case, whenever we give our DVMs this config, they will (re)broadcast
|
||||||
# their NIP89 announcement
|
# their NIP89 announcement
|
||||||
|
# You can create individual admins configs and hand them over when initializing the dvm,
|
||||||
|
# for example to whilelist users or add to their balance.
|
||||||
|
# If you use this global config, options will be set for all dvms that use it.
|
||||||
admin_config = AdminConfig()
|
admin_config = AdminConfig()
|
||||||
admin_config.REBROADCAST_NIP89 = False
|
admin_config.REBROADCAST_NIP89 = False
|
||||||
|
|
||||||
|
|
||||||
# Set rebroadcast to true once you have set your NIP89 descriptions and d tags. You only need to rebroadcast once you
|
# Set rebroadcast to true once you have set your NIP89 descriptions and d tags. You only need to rebroadcast once you
|
||||||
# want to update your NIP89 descriptions
|
# want to update your NIP89 descriptions
|
||||||
|
|
||||||
|
admin_config.UPDATE_PROFILE = False
|
||||||
|
admin_config.LUD16 = ""
|
||||||
|
|
||||||
def build_pdf_extractor(name):
|
|
||||||
|
# Auto update the profiles of your privkeys based on the nip89 information.
|
||||||
|
# Ideally set a lightning address in the LUD16 field above so our DVMs can get zapped from everywhere
|
||||||
|
|
||||||
|
|
||||||
|
# We build a couple of example dvms, create privatekeys and dtags and set their NIP89 descriptions
|
||||||
|
# We currently call these from the main function and start the dvms there.
|
||||||
|
|
||||||
|
def build_pdf_extractor(name, identifier):
|
||||||
dvm_config = DVMConfig()
|
dvm_config = DVMConfig()
|
||||||
dvm_config.PRIVATE_KEY = os.getenv("NOSTR_PRIVATE_KEY")
|
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||||
# Add NIP89
|
# Add NIP89
|
||||||
@@ -62,15 +72,15 @@ def build_pdf_extractor(name):
|
|||||||
}
|
}
|
||||||
|
|
||||||
nip89config = NIP89Config()
|
nip89config = NIP89Config()
|
||||||
nip89config.DTAG = os.getenv("TASK_TEXT_EXTRACTION_NIP89_DTAG")
|
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
|
||||||
nip89config.CONTENT = json.dumps(nip89info)
|
nip89config.CONTENT = json.dumps(nip89info)
|
||||||
return TextExtractionPDF(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
return TextExtractionPDF(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
||||||
admin_config=admin_config)
|
admin_config=admin_config)
|
||||||
|
|
||||||
|
|
||||||
def build_googletranslator(name):
|
def build_googletranslator(name, identifier):
|
||||||
dvm_config = DVMConfig()
|
dvm_config = DVMConfig()
|
||||||
dvm_config.PRIVATE_KEY = os.getenv("NOSTR_PRIVATE_KEY")
|
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||||
|
|
||||||
@@ -94,14 +104,15 @@ def build_googletranslator(name):
|
|||||||
"nip90Params": nip90params
|
"nip90Params": nip90params
|
||||||
}
|
}
|
||||||
nip89config = NIP89Config()
|
nip89config = NIP89Config()
|
||||||
nip89config.DTAG = os.getenv("TASK_TRANSLATION_NIP89_DTAG")
|
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
|
||||||
|
nip89info["image"])
|
||||||
nip89config.CONTENT = json.dumps(nip89info)
|
nip89config.CONTENT = json.dumps(nip89info)
|
||||||
return TranslationGoogle(name=name, dvm_config=dvm_config, nip89config=nip89config, admin_config=admin_config)
|
return TranslationGoogle(name=name, dvm_config=dvm_config, nip89config=nip89config, admin_config=admin_config)
|
||||||
|
|
||||||
|
|
||||||
def build_libretranslator(name):
|
def build_libretranslator(name, identifier):
|
||||||
dvm_config = DVMConfig()
|
dvm_config = DVMConfig()
|
||||||
dvm_config.PRIVATE_KEY = os.getenv("NOSTR_PRIVATE_KEY5")
|
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||||
|
|
||||||
@@ -127,15 +138,16 @@ def build_libretranslator(name):
|
|||||||
"nip90Params": nip90params
|
"nip90Params": nip90params
|
||||||
}
|
}
|
||||||
nip89config = NIP89Config()
|
nip89config = NIP89Config()
|
||||||
nip89config.DTAG = os.getenv("TASK_TRANSLATION_NIP89_DTAG6")
|
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
|
||||||
|
nip89info["image"])
|
||||||
nip89config.CONTENT = json.dumps(nip89info)
|
nip89config.CONTENT = json.dumps(nip89info)
|
||||||
return TranslationLibre(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
return TranslationLibre(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
||||||
admin_config=admin_config, options=options)
|
admin_config=admin_config, options=options)
|
||||||
|
|
||||||
|
|
||||||
def build_unstable_diffusion(name):
|
def build_unstable_diffusion(name, identifier):
|
||||||
dvm_config = DVMConfig()
|
dvm_config = DVMConfig()
|
||||||
dvm_config.PRIVATE_KEY = os.getenv("NOSTR_PRIVATE_KEY")
|
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||||
dvm_config.LNBITS_INVOICE_KEY = "" # This one will not use Lnbits to create invoices, but rely on zaps
|
dvm_config.LNBITS_INVOICE_KEY = "" # This one will not use Lnbits to create invoices, but rely on zaps
|
||||||
dvm_config.LNBITS_URL = ""
|
dvm_config.LNBITS_URL = ""
|
||||||
|
|
||||||
@@ -160,15 +172,16 @@ def build_unstable_diffusion(name):
|
|||||||
"nip90Params": nip90params
|
"nip90Params": nip90params
|
||||||
}
|
}
|
||||||
nip89config = NIP89Config()
|
nip89config = NIP89Config()
|
||||||
nip89config.DTAG = os.getenv("TASK_IMAGE_GENERATION_NIP89_DTAG")
|
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
|
||||||
|
nip89info["image"])
|
||||||
nip89config.CONTENT = json.dumps(nip89info)
|
nip89config.CONTENT = json.dumps(nip89info)
|
||||||
return ImageGenerationSDXL(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
return ImageGenerationSDXL(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
||||||
admin_config=admin_config, options=options)
|
admin_config=admin_config, options=options)
|
||||||
|
|
||||||
|
|
||||||
def build_whisperx(name):
|
def build_whisperx(name, identifier):
|
||||||
dvm_config = DVMConfig()
|
dvm_config = DVMConfig()
|
||||||
dvm_config.PRIVATE_KEY = os.getenv("NOSTR_PRIVATE_KEY4")
|
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||||
|
|
||||||
@@ -194,15 +207,16 @@ def build_whisperx(name):
|
|||||||
"nip90Params": nip90params
|
"nip90Params": nip90params
|
||||||
}
|
}
|
||||||
nip89config = NIP89Config()
|
nip89config = NIP89Config()
|
||||||
nip89config.DTAG = os.getenv("TASK_SPEECH_TO_TEXT_NIP89")
|
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
|
||||||
|
nip89info["image"])
|
||||||
nip89config.CONTENT = json.dumps(nip89info)
|
nip89config.CONTENT = json.dumps(nip89info)
|
||||||
return SpeechToTextWhisperX(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
return SpeechToTextWhisperX(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
||||||
admin_config=admin_config, options=options)
|
admin_config=admin_config, options=options)
|
||||||
|
|
||||||
|
|
||||||
def build_sketcher(name):
|
def build_sketcher(name, identifier):
|
||||||
dvm_config = DVMConfig()
|
dvm_config = DVMConfig()
|
||||||
dvm_config.PRIVATE_KEY = os.getenv("NOSTR_PRIVATE_KEY2")
|
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||||
|
|
||||||
@@ -228,16 +242,58 @@ def build_sketcher(name):
|
|||||||
options = {'default_model': "mohawk", 'default_lora': "timburton", 'nova_server': os.getenv("NOVA_SERVER")}
|
options = {'default_model': "mohawk", 'default_lora': "timburton", 'nova_server': os.getenv("NOVA_SERVER")}
|
||||||
|
|
||||||
nip89config = NIP89Config()
|
nip89config = NIP89Config()
|
||||||
nip89config.DTAG = os.getenv("TASK_IMAGE_GENERATION_NIP89_DTAG2")
|
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
|
||||||
|
nip89info["image"])
|
||||||
nip89config.CONTENT = json.dumps(nip89info)
|
nip89config.CONTENT = json.dumps(nip89info)
|
||||||
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
|
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
|
||||||
return ImageGenerationSDXL(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
return ImageGenerationSDXL(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
||||||
admin_config=admin_config, options=options)
|
admin_config=admin_config, options=options)
|
||||||
|
|
||||||
|
|
||||||
def build_dalle(name):
|
def build_image_converter(name, identifier):
|
||||||
dvm_config = DVMConfig()
|
dvm_config = DVMConfig()
|
||||||
dvm_config.PRIVATE_KEY = os.getenv("NOSTR_PRIVATE_KEY3")
|
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||||
|
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||||
|
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||||
|
|
||||||
|
nip90params = {
|
||||||
|
"negative_prompt": {
|
||||||
|
"required": False,
|
||||||
|
"values": []
|
||||||
|
},
|
||||||
|
"lora": {
|
||||||
|
"required": False,
|
||||||
|
"values": ["inkpunk", "timburton", "voxel"]
|
||||||
|
},
|
||||||
|
|
||||||
|
"strength": {
|
||||||
|
"required": False,
|
||||||
|
"values": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nip89info = {
|
||||||
|
"name": name,
|
||||||
|
"image": "https://image.nostr.build/229c14e440895da30de77b3ca145d66d4b04efb4027ba3c44ca147eecde891f1.jpg",
|
||||||
|
"about": "I convert an image to another image, kinda random for now. ",
|
||||||
|
"nip90Params": nip90params
|
||||||
|
}
|
||||||
|
|
||||||
|
# A module might have options it can be initialized with, here we set a default model, lora and the nova-server
|
||||||
|
options = {'default_lora': "inkpunk", 'strength': 0.5, 'nova_server': os.getenv("NOVA_SERVER")}
|
||||||
|
|
||||||
|
nip89config = NIP89Config()
|
||||||
|
|
||||||
|
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
|
||||||
|
nip89info["image"])
|
||||||
|
nip89config.CONTENT = json.dumps(nip89info)
|
||||||
|
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
|
||||||
|
return ImageGenerationSDXLIMG2IMG(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
||||||
|
admin_config=admin_config, options=options)
|
||||||
|
|
||||||
|
|
||||||
|
def build_dalle(name, identifier):
|
||||||
|
dvm_config = DVMConfig()
|
||||||
|
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||||
profit_in_sats = 10
|
profit_in_sats = 10
|
||||||
@@ -260,15 +316,16 @@ def build_dalle(name):
|
|||||||
# address it should use. These parameters can be freely defined in the task component
|
# address it should use. These parameters can be freely defined in the task component
|
||||||
|
|
||||||
nip89config = NIP89Config()
|
nip89config = NIP89Config()
|
||||||
nip89config.DTAG = os.getenv("TASK_IMAGE_GENERATION_NIP89_DTAG3")
|
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
|
||||||
|
nip89info["image"])
|
||||||
nip89config.CONTENT = json.dumps(nip89info)
|
nip89config.CONTENT = json.dumps(nip89info)
|
||||||
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
|
# We add an optional AdminConfig for this one, and tell the dvm to rebroadcast its NIP89
|
||||||
return ImageGenerationDALLE(name=name, dvm_config=dvm_config, nip89config=nip89config, admin_config=admin_config)
|
return ImageGenerationDALLE(name=name, dvm_config=dvm_config, nip89config=nip89config, admin_config=admin_config)
|
||||||
|
|
||||||
|
|
||||||
def build_media_converter(name):
|
def build_media_converter(name, identifier):
|
||||||
dvm_config = DVMConfig()
|
dvm_config = DVMConfig()
|
||||||
dvm_config.PRIVATE_KEY = os.getenv("NOSTR_PRIVATE_KEY6")
|
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||||
# Add NIP89
|
# Add NIP89
|
||||||
@@ -286,19 +343,15 @@ def build_media_converter(name):
|
|||||||
}
|
}
|
||||||
|
|
||||||
nip89config = NIP89Config()
|
nip89config = NIP89Config()
|
||||||
new_dtag = nip89_create_d_tag(name, Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_hex(),
|
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
|
||||||
nip89info["image"])
|
|
||||||
print("Some new dtag:" + new_dtag)
|
|
||||||
nip89config.DTAG = os.getenv("TASK_MEDIA_CONVERTER_NIP89_DTAG")
|
|
||||||
nip89config.CONTENT = json.dumps(nip89info)
|
nip89config.CONTENT = json.dumps(nip89info)
|
||||||
return MediaConverter(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
return MediaConverter(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
||||||
admin_config=admin_config)
|
admin_config=admin_config)
|
||||||
|
|
||||||
|
|
||||||
|
def build_inactive_follows_finder(name, identifier):
|
||||||
def build_inactive_follows_finder(name):
|
|
||||||
dvm_config = DVMConfig()
|
dvm_config = DVMConfig()
|
||||||
dvm_config.PRIVATE_KEY = os.getenv("NOSTR_PRIVATE_KEY7")
|
dvm_config.PRIVATE_KEY = check_and_set_private_key(identifier)
|
||||||
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
dvm_config.LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY")
|
||||||
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
dvm_config.LNBITS_URL = os.getenv("LNBITS_HOST")
|
||||||
# Add NIP89
|
# Add NIP89
|
||||||
@@ -323,14 +376,16 @@ def build_inactive_follows_finder(name):
|
|||||||
}
|
}
|
||||||
|
|
||||||
nip89config = NIP89Config()
|
nip89config = NIP89Config()
|
||||||
new_dtag = nip89_create_d_tag(name, Keys.from_sk_str(dvm_config.PRIVATE_KEY).public_key().to_hex(),
|
nip89config.DTAG = nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY,
|
||||||
nip89info["image"])
|
nip89info["image"])
|
||||||
print("Some new dtag:" + new_dtag)
|
|
||||||
nip89config.DTAG = os.getenv("TASK_DISCOVER_INACTIVE_NIP89_DTAG")
|
|
||||||
nip89config.CONTENT = json.dumps(nip89info)
|
nip89config.CONTENT = json.dumps(nip89info)
|
||||||
return DiscoverInactiveFollows(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
return DiscoverInactiveFollows(name=name, dvm_config=dvm_config, nip89config=nip89config,
|
||||||
admin_config=admin_config)
|
admin_config=admin_config)
|
||||||
|
|
||||||
|
|
||||||
|
# This function can be used to build a DVM object for a DVM we don't control, but we want the bot to be aware of.
|
||||||
|
# See main.py for examples.
|
||||||
def build_external_dvm(name, pubkey, task, kind, fix_cost, per_unit_cost):
|
def build_external_dvm(name, pubkey, task, kind, fix_cost, per_unit_cost):
|
||||||
dvm_config = DVMConfig()
|
dvm_config = DVMConfig()
|
||||||
dvm_config.PUBLIC_KEY = PublicKey.from_hex(pubkey).to_hex()
|
dvm_config.PUBLIC_KEY = PublicKey.from_hex(pubkey).to_hex()
|
||||||
@@ -346,8 +401,8 @@ def build_external_dvm(name, pubkey, task, kind, fix_cost, per_unit_cost):
|
|||||||
return DVMTaskInterface(name=name, dvm_config=dvm_config, nip89config=nip89config, task=task)
|
return DVMTaskInterface(name=name, dvm_config=dvm_config, nip89config=nip89config, task=task)
|
||||||
|
|
||||||
|
|
||||||
# Little Gimmick:
|
# Little optional Gimmick:
|
||||||
# For Dalle where we have to pay 4cent per image, we fetch current sat price in fiat
|
# For Dalle where we have to pay 4cent per image to openai, we fetch current sat price in fiat from coinstats api
|
||||||
# and update cost at each start
|
# and update cost at each start
|
||||||
def get_price_per_sat(currency):
|
def get_price_per_sat(currency):
|
||||||
import requests
|
import requests
|
||||||
|
@@ -6,12 +6,13 @@ Reusable backend functions can be defined in backends (e.g. API calls)
|
|||||||
|
|
||||||
Current List of Tasks:
|
Current List of Tasks:
|
||||||
|
|
||||||
| Module | Kind | Description | Backend |
|
| Module | Kind | Description | Backend |
|
||||||
|----------------------|------|------------------------------------------------|-------------|
|
|--------------------------|------|------------------------------------------------|-------------|
|
||||||
| TextExtractionPDF | 5000 | Extracts Text from a PDF file | local |
|
| TextExtractionPDF | 5000 | Extracts Text from a PDF file | local |
|
||||||
| SpeechToTextWhisperX | 5000 | Extracts Speech from Media files | nova-server |
|
| SpeechToTextWhisperX | 5000 | Extracts Speech from Media files | nova-server |
|
||||||
| TranslationGoogle | 5002 | Translates Inputs to another language | google API |
|
| TranslationGoogle | 5002 | Translates Inputs to another language | googleAPI |
|
||||||
| TranslationLibre | 5002 | Translates Inputs to another language | libre API |
|
| TranslationLibre | 5002 | Translates Inputs to another language | libreAPI |
|
||||||
| ImageGenerationSDXL | 5100 | Generates an Image with StableDiffusionXL | nova-server |
|
| ImageGenerationSDXL | 5100 | Generates an Image with StableDiffusionXL | nova-server |
|
||||||
| ImageGenerationDALLE | 5100 | Generates an Image with Dall-E | openAI |
|
| ImageGenerationDALLE | 5100 | Generates an Image with Dall-E | openAI |
|
||||||
| MediaConverter | 5300 | Converts a link of a media file and uploads it | openAI |
|
| MediaConverter | 5200 | Converts a link of a media file and uploads it | openAI |
|
||||||
|
| DiscoverInactiveFollows | 5301 | Find inactive Nostr users | local |
|
@@ -82,9 +82,9 @@ class ImageGenerationSDXL(DVMTaskInterface):
|
|||||||
elif tag.as_vec()[1] == "lora_weight":
|
elif tag.as_vec()[1] == "lora_weight":
|
||||||
lora_weight = tag.as_vec()[2]
|
lora_weight = tag.as_vec()[2]
|
||||||
elif tag.as_vec()[1] == "strength":
|
elif tag.as_vec()[1] == "strength":
|
||||||
strength = tag.as_vec()[2]
|
strength = float(tag.as_vec()[2])
|
||||||
elif tag.as_vec()[1] == "guidance_scale":
|
elif tag.as_vec()[1] == "guidance_scale":
|
||||||
guidance_scale = tag.as_vec()[2]
|
guidance_scale = float(tag.as_vec()[2])
|
||||||
elif tag.as_vec()[1] == "ratio":
|
elif tag.as_vec()[1] == "ratio":
|
||||||
if len(tag.as_vec()) > 3:
|
if len(tag.as_vec()) > 3:
|
||||||
ratio_width = (tag.as_vec()[2])
|
ratio_width = (tag.as_vec()[2])
|
||||||
|
186
tasks/imagegeneration_sdxlimg2img.py
Normal file
186
tasks/imagegeneration_sdxlimg2img.py
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
import json
|
||||||
|
from multiprocessing.pool import ThreadPool
|
||||||
|
|
||||||
|
from backends.nova_server import check_nova_server_status, send_request_to_nova_server
|
||||||
|
from interfaces.dvmtaskinterface import DVMTaskInterface
|
||||||
|
from utils.admin_utils import AdminConfig
|
||||||
|
from utils.dvmconfig import DVMConfig
|
||||||
|
from utils.nip89_utils import NIP89Config
|
||||||
|
from utils.definitions import EventDefinitions
|
||||||
|
|
||||||
|
"""
|
||||||
|
This File contains a Module to transform Text input on NOVA-Server and receive results back.
|
||||||
|
|
||||||
|
Accepted Inputs: Prompt (text)
|
||||||
|
Outputs: An url to an Image
|
||||||
|
Params: -model # models: juggernaut, dynavision, colossusProject, newreality, unstable
|
||||||
|
-lora # loras (weights on top of models) voxel,
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ImageGenerationSDXLIMG2IMG(DVMTaskInterface):
|
||||||
|
KIND: int = EventDefinitions.KIND_NIP90_GENERATE_IMAGE
|
||||||
|
TASK: str = "image-to-image"
|
||||||
|
FIX_COST: float = 50
|
||||||
|
|
||||||
|
def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config,
|
||||||
|
admin_config: AdminConfig = None, options=None):
|
||||||
|
super().__init__(name, dvm_config, nip89config, admin_config, options)
|
||||||
|
|
||||||
|
def is_input_supported(self, tags):
|
||||||
|
hasurl = False
|
||||||
|
hasprompt = False
|
||||||
|
for tag in tags:
|
||||||
|
if tag.as_vec()[0] == 'i':
|
||||||
|
input_value = tag.as_vec()[1]
|
||||||
|
input_type = tag.as_vec()[2]
|
||||||
|
if input_type == "url":
|
||||||
|
hasurl = True
|
||||||
|
elif input_type == "text":
|
||||||
|
hasprompt = True #Little optional when lora is set
|
||||||
|
|
||||||
|
elif tag.as_vec()[0] == 'output':
|
||||||
|
output = tag.as_vec()[1]
|
||||||
|
if (output == "" or
|
||||||
|
not (output == "image/png" or "image/jpg"
|
||||||
|
or output == "image/png;format=url" or output == "image/jpg;format=url")):
|
||||||
|
print("Output format not supported, skipping..")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not hasurl:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def create_request_form_from_nostr_event(self, event, client=None, dvm_config=None):
|
||||||
|
request_form = {"jobID": event.id().to_hex() + "_" + self.NAME.replace(" ", "")}
|
||||||
|
request_form["trainerFilePath"] = r'modules\stablediffusionxl\stablediffusionxl-img2img.trainer'
|
||||||
|
|
||||||
|
prompt = ""
|
||||||
|
negative_prompt = ""
|
||||||
|
url = ""
|
||||||
|
if self.options.get("default_model"):
|
||||||
|
model = self.options['default_model']
|
||||||
|
else:
|
||||||
|
model = "stabilityai/stable-diffusion-xl-refiner-1.0"
|
||||||
|
|
||||||
|
ratio_width = "1"
|
||||||
|
ratio_height = "1"
|
||||||
|
width = ""
|
||||||
|
height = ""
|
||||||
|
|
||||||
|
if self.options.get("default_lora"):
|
||||||
|
lora = self.options['default_lora']
|
||||||
|
else:
|
||||||
|
lora = ""
|
||||||
|
|
||||||
|
lora_weight = ""
|
||||||
|
if self.options.get("strength"):
|
||||||
|
strength = float(self.options['strength'])
|
||||||
|
else:
|
||||||
|
strength = 0.8
|
||||||
|
if self.options.get("guidance_scale"):
|
||||||
|
guidance_scale = float(self.options['guidance_scale'])
|
||||||
|
else:
|
||||||
|
guidance_scale = 11.0
|
||||||
|
for tag in event.tags():
|
||||||
|
if tag.as_vec()[0] == 'i':
|
||||||
|
input_type = tag.as_vec()[2]
|
||||||
|
if input_type == "text":
|
||||||
|
prompt = tag.as_vec()[1]
|
||||||
|
elif input_type == "url":
|
||||||
|
url = tag.as_vec()[1]
|
||||||
|
|
||||||
|
elif tag.as_vec()[0] == 'param':
|
||||||
|
print("Param: " + tag.as_vec()[1] + ": " + tag.as_vec()[2])
|
||||||
|
if tag.as_vec()[1] == "negative_prompt":
|
||||||
|
negative_prompt = tag.as_vec()[2]
|
||||||
|
elif tag.as_vec()[1] == "lora":
|
||||||
|
lora = tag.as_vec()[2]
|
||||||
|
elif tag.as_vec()[1] == "lora_weight":
|
||||||
|
lora_weight = tag.as_vec()[2]
|
||||||
|
elif tag.as_vec()[1] == "strength":
|
||||||
|
strength = float(tag.as_vec()[2])
|
||||||
|
elif tag.as_vec()[1] == "guidance_scale":
|
||||||
|
guidance_scale = float(tag.as_vec()[2])
|
||||||
|
elif tag.as_vec()[1] == "ratio":
|
||||||
|
if len(tag.as_vec()) > 3:
|
||||||
|
ratio_width = (tag.as_vec()[2])
|
||||||
|
ratio_height = (tag.as_vec()[3])
|
||||||
|
elif len(tag.as_vec()) == 3:
|
||||||
|
split = tag.as_vec()[2].split(":")
|
||||||
|
ratio_width = split[0]
|
||||||
|
ratio_height = split[1]
|
||||||
|
# if size is set it will overwrite ratio.
|
||||||
|
elif tag.as_vec()[1] == "size":
|
||||||
|
if len(tag.as_vec()) > 3:
|
||||||
|
width = (tag.as_vec()[2])
|
||||||
|
height = (tag.as_vec()[3])
|
||||||
|
elif len(tag.as_vec()) == 3:
|
||||||
|
split = tag.as_vec()[2].split("x")
|
||||||
|
if len(split) > 1:
|
||||||
|
width = split[0]
|
||||||
|
height = split[1]
|
||||||
|
elif tag.as_vec()[1] == "model":
|
||||||
|
model = tag.as_vec()[2]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
io_input_image = {
|
||||||
|
"id": "input_image",
|
||||||
|
"type": "input",
|
||||||
|
"src": "url:Image",
|
||||||
|
"uri": url
|
||||||
|
}
|
||||||
|
io_input = {
|
||||||
|
"id": "input_prompt",
|
||||||
|
"type": "input",
|
||||||
|
"src": "request:text",
|
||||||
|
"data": prompt
|
||||||
|
}
|
||||||
|
io_negative = {
|
||||||
|
"id": "negative_prompt",
|
||||||
|
"type": "input",
|
||||||
|
"src": "request:text",
|
||||||
|
"data": negative_prompt
|
||||||
|
}
|
||||||
|
io_output = {
|
||||||
|
"id": "output_image",
|
||||||
|
"type": "output",
|
||||||
|
"src": "request:image"
|
||||||
|
}
|
||||||
|
|
||||||
|
request_form['data'] = json.dumps([io_input_image, io_input, io_negative, io_output])
|
||||||
|
|
||||||
|
options = {
|
||||||
|
"model": model,
|
||||||
|
"ratio": ratio_width + '-' + ratio_height,
|
||||||
|
"width": width,
|
||||||
|
"height": height,
|
||||||
|
"strength": strength,
|
||||||
|
"guidance_scale": guidance_scale,
|
||||||
|
"lora": lora,
|
||||||
|
"lora_weight": lora_weight,
|
||||||
|
"n_steps": 30
|
||||||
|
}
|
||||||
|
request_form['options'] = json.dumps(options)
|
||||||
|
|
||||||
|
return request_form
|
||||||
|
|
||||||
|
def process(self, request_form):
|
||||||
|
try:
|
||||||
|
# Call the process route of NOVA-Server with our request form.
|
||||||
|
response = send_request_to_nova_server(request_form, self.options['nova_server'])
|
||||||
|
if bool(json.loads(response)['success']):
|
||||||
|
print("Job " + request_form['jobID'] + " sent to NOVA-server")
|
||||||
|
|
||||||
|
pool = ThreadPool(processes=1)
|
||||||
|
thread = pool.apply_async(check_nova_server_status, (request_form['jobID'], self.options['nova_server']))
|
||||||
|
print("Wait for results of NOVA-Server...")
|
||||||
|
result = thread.get()
|
||||||
|
return result
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(e)
|
@@ -10,13 +10,13 @@ from nostr_sdk import Keys, Client, Tag, EventBuilder, Filter, HandleNotificatio
|
|||||||
nip04_encrypt
|
nip04_encrypt
|
||||||
|
|
||||||
from utils.dvmconfig import DVMConfig
|
from utils.dvmconfig import DVMConfig
|
||||||
from utils.nostr_utils import send_event
|
from utils.nostr_utils import send_event, check_and_set_private_key
|
||||||
from utils.definitions import EventDefinitions
|
from utils.definitions import EventDefinitions
|
||||||
|
|
||||||
|
|
||||||
# TODO HINT: Best use this path with a previously whitelisted privkey, as zapping events is not implemented in the lib/code
|
# TODO HINT: Best use this path with a previously whitelisted privkey, as zapping events is not implemented in the lib/code
|
||||||
def nostr_client_test_translation(input, kind, lang, sats, satsmax):
|
def nostr_client_test_translation(input, kind, lang, sats, satsmax):
|
||||||
keys = Keys.from_sk_str(os.getenv("NOSTR_TEST_CLIENT_PRIVATE_KEY"))
|
keys = Keys.from_sk_str(check_and_set_private_key("test_client"))
|
||||||
if kind == "text":
|
if kind == "text":
|
||||||
iTag = Tag.parse(["i", input, "text"])
|
iTag = Tag.parse(["i", input, "text"])
|
||||||
elif kind == "event":
|
elif kind == "event":
|
||||||
@@ -43,7 +43,7 @@ def nostr_client_test_translation(input, kind, lang, sats, satsmax):
|
|||||||
|
|
||||||
|
|
||||||
def nostr_client_test_image(prompt):
|
def nostr_client_test_image(prompt):
|
||||||
keys = Keys.from_sk_str(os.getenv("NOSTR_TEST_CLIENT_PRIVATE_KEY"))
|
keys = Keys.from_sk_str(check_and_set_private_key("test_client"))
|
||||||
|
|
||||||
iTag = Tag.parse(["i", prompt, "text"])
|
iTag = Tag.parse(["i", prompt, "text"])
|
||||||
outTag = Tag.parse(["output", "image/png;format=url"])
|
outTag = Tag.parse(["output", "image/png;format=url"])
|
||||||
@@ -70,8 +70,8 @@ def nostr_client_test_image(prompt):
|
|||||||
|
|
||||||
|
|
||||||
def nostr_client_test_image_private(prompt, cashutoken):
|
def nostr_client_test_image_private(prompt, cashutoken):
|
||||||
keys = Keys.from_sk_str(os.getenv("NOSTR_TEST_CLIENT_PRIVATE_KEY"))
|
keys = Keys.from_sk_str(check_and_set_private_key("test_client"))
|
||||||
receiver_keys = Keys.from_sk_str(os.getenv("NOSTR_PRIVATE_KEY"))
|
receiver_keys = Keys.from_sk_str(check_and_set_private_key("sketcher"))
|
||||||
|
|
||||||
|
|
||||||
# TODO more advanced logic, more parsing, params etc, just very basic test functions for now
|
# TODO more advanced logic, more parsing, params etc, just very basic test functions for now
|
||||||
@@ -109,7 +109,7 @@ def nostr_client_test_image_private(prompt, cashutoken):
|
|||||||
return nip90request.as_json()
|
return nip90request.as_json()
|
||||||
|
|
||||||
def nostr_client():
|
def nostr_client():
|
||||||
keys = Keys.from_sk_str(os.getenv("NOSTR_TEST_CLIENT_PRIVATE_KEY"))
|
keys = Keys.from_sk_str(check_and_set_private_key("test_client"))
|
||||||
sk = keys.secret_key()
|
sk = keys.secret_key()
|
||||||
pk = keys.public_key()
|
pk = keys.public_key()
|
||||||
print(f"Nostr Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ")
|
print(f"Nostr Client public key: {pk.to_bech32()}, Hex: {pk.to_hex()} ")
|
||||||
@@ -127,13 +127,13 @@ def nostr_client():
|
|||||||
client.subscribe([dm_zap_filter, dvm_filter])
|
client.subscribe([dm_zap_filter, dvm_filter])
|
||||||
|
|
||||||
#nostr_client_test_translation("This is the result of the DVM in spanish", "text", "es", 20, 20)
|
#nostr_client_test_translation("This is the result of the DVM in spanish", "text", "es", 20, 20)
|
||||||
#nostr_client_test_translation("note1p8cx2dz5ss5gnk7c59zjydcncx6a754c0hsyakjvnw8xwlm5hymsnc23rs", "event", "es", 20,20)
|
nostr_client_test_translation("note1p8cx2dz5ss5gnk7c59zjydcncx6a754c0hsyakjvnw8xwlm5hymsnc23rs", "event", "es", 20,20)
|
||||||
#nostr_client_test_translation("44a0a8b395ade39d46b9d20038b3f0c8a11168e67c442e3ece95e4a1703e2beb", "event", "zh", 20, 20)
|
#nostr_client_test_translation("44a0a8b395ade39d46b9d20038b3f0c8a11168e67c442e3ece95e4a1703e2beb", "event", "zh", 20, 20)
|
||||||
|
|
||||||
#nostr_client_test_image("a beautiful purple ostrich watching the sunset")
|
#nostr_client_test_image("a beautiful purple ostrich watching the sunset")
|
||||||
|
|
||||||
cashutoken = "cashuAeyJ0b2tlbiI6W3sicHJvb2ZzIjpbeyJpZCI6InZxc1VRSVorb0sxOSIsImFtb3VudCI6MSwiQyI6IjAyNWU3ODZhOGFkMmExYTg0N2YxMzNiNGRhM2VhMGIyYWRhZGFkOTRiYzA4M2E2NWJjYjFlOTgwYTE1NGIyMDA2NCIsInNlY3JldCI6InQ1WnphMTZKMGY4UElQZ2FKTEg4V3pPck5rUjhESWhGa291LzVzZFd4S0U9In0seyJpZCI6InZxc1VRSVorb0sxOSIsImFtb3VudCI6NCwiQyI6IjAyOTQxNmZmMTY2MzU5ZWY5ZDc3MDc2MGNjZmY0YzliNTMzMzVmZTA2ZGI5YjBiZDg2Njg5Y2ZiZTIzMjVhYWUwYiIsInNlY3JldCI6IlRPNHB5WE43WlZqaFRQbnBkQ1BldWhncm44UHdUdE5WRUNYWk9MTzZtQXM9In0seyJpZCI6InZxc1VRSVorb0sxOSIsImFtb3VudCI6MTYsIkMiOiIwMmRiZTA3ZjgwYmMzNzE0N2YyMDJkNTZiMGI3ZTIzZTdiNWNkYTBhNmI3Yjg3NDExZWYyOGRiZDg2NjAzNzBlMWIiLCJzZWNyZXQiOiJHYUNIdHhzeG9HM3J2WWNCc0N3V0YxbU1NVXczK0dDN1RKRnVwOHg1cURzPSJ9XSwibWludCI6Imh0dHBzOi8vbG5iaXRzLmJpdGNvaW5maXhlc3RoaXMub3JnL2Nhc2h1L2FwaS92MS9ScDlXZGdKZjlxck51a3M1eVQ2SG5rIn1dfQ=="
|
#cashutoken = "cashuAeyJ0b2tlbiI6W3sicHJvb2ZzIjpbeyJpZCI6InZxc1VRSVorb0sxOSIsImFtb3VudCI6MSwiQyI6IjAyNWU3ODZhOGFkMmExYTg0N2YxMzNiNGRhM2VhMGIyYWRhZGFkOTRiYzA4M2E2NWJjYjFlOTgwYTE1NGIyMDA2NCIsInNlY3JldCI6InQ1WnphMTZKMGY4UElQZ2FKTEg4V3pPck5rUjhESWhGa291LzVzZFd4S0U9In0seyJpZCI6InZxc1VRSVorb0sxOSIsImFtb3VudCI6NCwiQyI6IjAyOTQxNmZmMTY2MzU5ZWY5ZDc3MDc2MGNjZmY0YzliNTMzMzVmZTA2ZGI5YjBiZDg2Njg5Y2ZiZTIzMjVhYWUwYiIsInNlY3JldCI6IlRPNHB5WE43WlZqaFRQbnBkQ1BldWhncm44UHdUdE5WRUNYWk9MTzZtQXM9In0seyJpZCI6InZxc1VRSVorb0sxOSIsImFtb3VudCI6MTYsIkMiOiIwMmRiZTA3ZjgwYmMzNzE0N2YyMDJkNTZiMGI3ZTIzZTdiNWNkYTBhNmI3Yjg3NDExZWYyOGRiZDg2NjAzNzBlMWIiLCJzZWNyZXQiOiJHYUNIdHhzeG9HM3J2WWNCc0N3V0YxbU1NVXczK0dDN1RKRnVwOHg1cURzPSJ9XSwibWludCI6Imh0dHBzOi8vbG5iaXRzLmJpdGNvaW5maXhlc3RoaXMub3JnL2Nhc2h1L2FwaS92MS9ScDlXZGdKZjlxck51a3M1eVQ2SG5rIn1dfQ=="
|
||||||
nostr_client_test_image_private("a beautiful ostrich watching the sunset", cashutoken )
|
#nostr_client_test_image_private("a beautiful ostrich watching the sunset", cashutoken )
|
||||||
class NotificationHandler(HandleNotification):
|
class NotificationHandler(HandleNotification):
|
||||||
def handle(self, relay_url, event):
|
def handle(self, relay_url, event):
|
||||||
print(f"Received new event from {relay_url}: {event.as_json()}")
|
print(f"Received new event from {relay_url}: {event.as_json()}")
|
||||||
@@ -161,7 +161,7 @@ def nostr_client():
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
env_path = Path('../.env')
|
env_path = Path('.env')
|
||||||
if env_path.is_file():
|
if env_path.is_file():
|
||||||
print(f'loading environment from {env_path.resolve()}')
|
print(f'loading environment from {env_path.resolve()}')
|
||||||
dotenv.load_dotenv(env_path, verbose=True, override=True)
|
dotenv.load_dotenv(env_path, verbose=True, override=True)
|
||||||
|
@@ -6,18 +6,23 @@ from nostr_sdk import Keys, EventBuilder, PublicKey
|
|||||||
from utils.database_utils import get_from_sql_table, list_db, delete_from_sql_table, update_sql_table, \
|
from utils.database_utils import get_from_sql_table, list_db, delete_from_sql_table, update_sql_table, \
|
||||||
get_or_add_user, clean_db
|
get_or_add_user, clean_db
|
||||||
from utils.dvmconfig import DVMConfig
|
from utils.dvmconfig import DVMConfig
|
||||||
from utils.nip89_utils import nip89_announce_tasks
|
from utils.nip89_utils import nip89_announce_tasks, NIP89Config
|
||||||
from utils.nostr_utils import send_event
|
from utils.nostr_utils import send_event, update_profile
|
||||||
|
|
||||||
|
|
||||||
class AdminConfig:
|
class AdminConfig:
|
||||||
REBROADCAST_NIP89: bool = False
|
REBROADCAST_NIP89: bool = False
|
||||||
|
UPDATE_PROFILE: bool = False
|
||||||
WHITELISTUSER: bool = False
|
WHITELISTUSER: bool = False
|
||||||
UNWHITELISTUSER: bool = False
|
UNWHITELISTUSER: bool = False
|
||||||
BLACKLISTUSER: bool = False
|
BLACKLISTUSER: bool = False
|
||||||
DELETEUSER: bool = False
|
DELETEUSER: bool = False
|
||||||
LISTDATABASE: bool = False
|
LISTDATABASE: bool = False
|
||||||
ClEANDB: bool = False
|
ClEANDB: bool = False
|
||||||
|
|
||||||
USERNPUB: str = ""
|
USERNPUB: str = ""
|
||||||
|
LUD16: str = ""
|
||||||
|
|
||||||
|
|
||||||
def admin_make_database_updates(adminconfig: AdminConfig = None, dvmconfig: DVMConfig = None, client=None):
|
def admin_make_database_updates(adminconfig: AdminConfig = None, dvmconfig: DVMConfig = None, client=None):
|
||||||
# This is called on start of Server, Admin function to manually whitelist/blacklist/add balance/delete users
|
# This is called on start of Server, Admin function to manually whitelist/blacklist/add balance/delete users
|
||||||
@@ -31,46 +36,43 @@ def admin_make_database_updates(adminconfig: AdminConfig = None, dvmconfig: DVMC
|
|||||||
and adminconfig.USERNPUB == ""):
|
and adminconfig.USERNPUB == ""):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if adminconfig.UPDATE_PROFILE and (dvmconfig.NIP89 is None):
|
||||||
|
return
|
||||||
|
|
||||||
db = dvmconfig.DB
|
db = dvmconfig.DB
|
||||||
|
|
||||||
rebroadcast_nip89 = adminconfig.REBROADCAST_NIP89
|
if str(adminconfig.USERNPUB).startswith("npub"):
|
||||||
cleandb = adminconfig.ClEANDB
|
publickey = PublicKey.from_bech32(adminconfig.USERNPUB).to_hex()
|
||||||
listdatabase = adminconfig.LISTDATABASE
|
else:
|
||||||
deleteuser = adminconfig.DELETEUSER
|
publickey = adminconfig.USERNPUB
|
||||||
whitelistuser = adminconfig.WHITELISTUSER
|
|
||||||
unwhitelistuser = adminconfig.UNWHITELISTUSER
|
|
||||||
blacklistuser = adminconfig.BLACKLISTUSER
|
|
||||||
|
|
||||||
if adminconfig.USERNPUB != "":
|
if adminconfig.WHITELISTUSER:
|
||||||
if str(adminconfig.USERNPUB).startswith("npub"):
|
|
||||||
publickey = PublicKey.from_bech32(adminconfig.USERNPUB).to_hex()
|
|
||||||
else:
|
|
||||||
publickey = adminconfig.USERNPUB
|
|
||||||
|
|
||||||
|
|
||||||
if whitelistuser:
|
|
||||||
user = get_or_add_user(db, publickey, client=client, config=dvmconfig)
|
user = get_or_add_user(db, publickey, client=client, config=dvmconfig)
|
||||||
update_sql_table(db, user.npub, user.balance, True, False, user.nip05, user.lud16, user.name, user.lastactive)
|
update_sql_table(db, user.npub, user.balance, True, False, user.nip05, user.lud16, user.name, user.lastactive)
|
||||||
user = get_from_sql_table(db, publickey)
|
user = get_from_sql_table(db, publickey)
|
||||||
print(str(user.name) + " is whitelisted: " + str(user.iswhitelisted))
|
print(str(user.name) + " is whitelisted: " + str(user.iswhitelisted))
|
||||||
|
|
||||||
if unwhitelistuser:
|
|
||||||
|
if adminconfig.UNWHITELISTUSER:
|
||||||
user = get_from_sql_table(db, publickey)
|
user = get_from_sql_table(db, publickey)
|
||||||
update_sql_table(db, user.npub, user.balance, False, False, user.nip05, user.lud16, user.name, user.lastactive)
|
update_sql_table(db, user.npub, user.balance, False, False, user.nip05, user.lud16, user.name, user.lastactive)
|
||||||
|
|
||||||
if blacklistuser:
|
if adminconfig.BLACKLISTUSER:
|
||||||
user = get_from_sql_table(db, publickey)
|
user = get_from_sql_table(db, publickey)
|
||||||
update_sql_table(db, user.npub, user.balance, False, True, user.nip05, user.lud16, user.name, user.lastactive)
|
update_sql_table(db, user.npub, user.balance, False, True, user.nip05, user.lud16, user.name, user.lastactive)
|
||||||
|
|
||||||
if deleteuser:
|
if adminconfig.DELETEUSER:
|
||||||
delete_from_sql_table(db, publickey)
|
delete_from_sql_table(db, publickey)
|
||||||
|
|
||||||
if cleandb:
|
if adminconfig.ClEANDB:
|
||||||
clean_db(db)
|
clean_db(db)
|
||||||
|
|
||||||
if listdatabase:
|
if adminconfig.LISTDATABASE:
|
||||||
list_db(db)
|
list_db(db)
|
||||||
|
|
||||||
if rebroadcast_nip89:
|
if adminconfig.REBROADCAST_NIP89:
|
||||||
nip89_announce_tasks(dvmconfig, client=client)
|
nip89_announce_tasks(dvmconfig, client=client)
|
||||||
|
|
||||||
|
if adminconfig.UPDATE_PROFILE:
|
||||||
|
update_profile(dvmconfig, lud16=adminconfig.LUD16)
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ from nostr_sdk import Event, Tag
|
|||||||
|
|
||||||
from utils.definitions import EventDefinitions
|
from utils.definitions import EventDefinitions
|
||||||
from utils.mediasource_utils import check_source_type, media_source
|
from utils.mediasource_utils import check_source_type, media_source
|
||||||
from utils.nostr_utils import get_event_by_id
|
from utils.nostr_utils import get_event_by_id, get_referenced_event_by_id
|
||||||
|
|
||||||
|
|
||||||
def get_task(event, client, dvm_config):
|
def get_task(event, client, dvm_config):
|
||||||
@@ -53,8 +53,38 @@ def get_task(event, client, dvm_config):
|
|||||||
return "unknown type"
|
return "unknown type"
|
||||||
else:
|
else:
|
||||||
return "unknown job"
|
return "unknown job"
|
||||||
|
elif event.kind() == EventDefinitions.KIND_NIP90_GENERATE_IMAGE:
|
||||||
|
has_image_tag = False
|
||||||
|
has_text_tag = False
|
||||||
|
for tag in event.tags():
|
||||||
|
if tag.as_vec()[0] == "i":
|
||||||
|
if tag.as_vec()[2] == "url":
|
||||||
|
file_type = check_url_is_readable(tag.as_vec()[1])
|
||||||
|
if file_type == "image":
|
||||||
|
has_image_tag = True
|
||||||
|
print("found image tag")
|
||||||
|
elif tag.as_vec()[2] == "job":
|
||||||
|
evt = get_referenced_event_by_id(event_id=tag.as_vec()[1], kinds=
|
||||||
|
[EventDefinitions.KIND_NIP90_RESULT_EXTRACT_TEXT,
|
||||||
|
EventDefinitions.KIND_NIP90_RESULT_TRANSLATE_TEXT,
|
||||||
|
EventDefinitions.KIND_NIP90_RESULT_SUMMARIZE_TEXT],
|
||||||
|
client=client,
|
||||||
|
dvm_config=dvm_config)
|
||||||
|
if evt is not None:
|
||||||
|
file_type = check_url_is_readable(evt.content())
|
||||||
|
if file_type == "image":
|
||||||
|
has_image_tag = True
|
||||||
|
elif tag.as_vec()[2] == "text":
|
||||||
|
has_text_tag = True
|
||||||
|
|
||||||
|
if has_image_tag:
|
||||||
|
return "image-to-image"
|
||||||
|
elif has_text_tag and not has_image_tag:
|
||||||
|
return "text-to-image"
|
||||||
# TODO if a task can consist of multiple inputs add them here
|
# TODO if a task can consist of multiple inputs add them here
|
||||||
|
# This is not ideal. Maybe such events should have their own kind
|
||||||
|
|
||||||
|
|
||||||
# else if kind is supported, simply return task
|
# else if kind is supported, simply return task
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
|
import os
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import dotenv
|
||||||
from nostr_sdk import Tag, Keys, EventBuilder, Filter, Alphabet, PublicKey, Event
|
from nostr_sdk import Tag, Keys, EventBuilder, Filter, Alphabet, PublicKey, Event
|
||||||
|
|
||||||
from utils.definitions import EventDefinitions
|
from utils.definitions import EventDefinitions
|
||||||
@@ -16,21 +19,17 @@ class NIP89Config:
|
|||||||
|
|
||||||
|
|
||||||
def nip89_create_d_tag(name, pubkey, image):
|
def nip89_create_d_tag(name, pubkey, image):
|
||||||
#import hashlib
|
|
||||||
#m = hashlib.md5()
|
|
||||||
#m.update(str(name + image + pubkey).encode("utf-8"))
|
|
||||||
#d_tag = m.hexdigest()[0:16]
|
|
||||||
|
|
||||||
key_str = str(name + image + pubkey)
|
key_str = str(name + image + pubkey)
|
||||||
d_tag = sha256(key_str.encode('utf-8')).hexdigest()[:16]
|
d_tag = sha256(key_str.encode('utf-8')).hexdigest()[:16]
|
||||||
return d_tag
|
return d_tag
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def nip89_announce_tasks(dvm_config, client):
|
def nip89_announce_tasks(dvm_config, client):
|
||||||
k_tag = Tag.parse(["k", str(dvm_config.NIP89.kind)])
|
k_tag = Tag.parse(["k", str(dvm_config.NIP89.KIND)])
|
||||||
d_tag = Tag.parse(["d", dvm_config.NIP89.dtag])
|
d_tag = Tag.parse(["d", dvm_config.NIP89.DTAG])
|
||||||
keys = Keys.from_sk_str(dvm_config.NIP89.pk)
|
keys = Keys.from_sk_str(dvm_config.NIP89.PK)
|
||||||
content = dvm_config.NIP89.content
|
content = dvm_config.NIP89.CONTENT
|
||||||
event = EventBuilder(EventDefinitions.KIND_ANNOUNCEMENT, content, [k_tag, d_tag]).to_event(keys)
|
event = EventBuilder(EventDefinitions.KIND_ANNOUNCEMENT, content, [k_tag, d_tag]).to_event(keys)
|
||||||
send_event(event, client=client, dvm_config=dvm_config)
|
send_event(event, client=client, dvm_config=dvm_config)
|
||||||
print("Announced NIP 89 for " + dvm_config.NIP89.NAME)
|
print("Announced NIP 89 for " + dvm_config.NIP89.NAME)
|
||||||
@@ -66,3 +65,21 @@ def nip89_fetch_events_pubkey(client, pubkey, kind):
|
|||||||
# should be one element of the kind now
|
# should be one element of the kind now
|
||||||
for dvm in dvms:
|
for dvm in dvms:
|
||||||
return dvms[dvm].content()
|
return dvms[dvm].content()
|
||||||
|
|
||||||
|
|
||||||
|
def check_and_set_d_tag(identifier, name, pk, imageurl):
|
||||||
|
if not os.getenv("NIP89_DTAG_" + identifier.upper()):
|
||||||
|
new_dtag = nip89_create_d_tag(name, Keys.from_sk_str(pk).public_key().to_hex(),
|
||||||
|
imageurl)
|
||||||
|
nip89_add_dtag_to_env_file("NIP89_DTAG_" + identifier.upper(), new_dtag)
|
||||||
|
print("Some new dtag:" + new_dtag)
|
||||||
|
return new_dtag
|
||||||
|
else:
|
||||||
|
return os.getenv("NIP89_DTAG_" + identifier.upper())
|
||||||
|
|
||||||
|
def nip89_add_dtag_to_env_file(dtag, oskey):
|
||||||
|
env_path = Path('.env')
|
||||||
|
if env_path.is_file():
|
||||||
|
print(f'loading environment from {env_path.resolve()}')
|
||||||
|
dotenv.load_dotenv(env_path, verbose=True, override=True)
|
||||||
|
dotenv.set_key(env_path, dtag, oskey)
|
@@ -1,6 +1,10 @@
|
|||||||
import json
|
import json
|
||||||
|
import os
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from nostr_sdk import Filter, Client, Alphabet, EventId, Event, PublicKey, Tag, Keys, nip04_decrypt
|
from pathlib import Path
|
||||||
|
|
||||||
|
import dotenv
|
||||||
|
from nostr_sdk import Filter, Client, Alphabet, EventId, Event, PublicKey, Tag, Keys, nip04_decrypt, Metadata, Options
|
||||||
|
|
||||||
|
|
||||||
def get_event_by_id(event_id: str, client: Client, config=None) -> Event | None:
|
def get_event_by_id(event_id: str, client: Client, config=None) -> Event | None:
|
||||||
@@ -99,6 +103,7 @@ def check_and_decrypt_tags(event, dvm_config):
|
|||||||
|
|
||||||
return event
|
return event
|
||||||
|
|
||||||
|
|
||||||
def check_and_decrypt_own_tags(event, dvm_config):
|
def check_and_decrypt_own_tags(event, dvm_config):
|
||||||
try:
|
try:
|
||||||
tags = []
|
tags = []
|
||||||
@@ -131,3 +136,57 @@ def check_and_decrypt_own_tags(event, dvm_config):
|
|||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
return event
|
return event
|
||||||
|
|
||||||
|
|
||||||
|
def update_profile(dvm_config, lud16=""):
|
||||||
|
keys = Keys.from_sk_str(dvm_config.PRIVATE_KEY)
|
||||||
|
opts = (Options().wait_for_send(True).send_timeout(timedelta(seconds=dvm_config.RELAY_TIMEOUT))
|
||||||
|
.skip_disconnected_relays(True))
|
||||||
|
|
||||||
|
client = Client.with_opts(keys, opts)
|
||||||
|
for relay in dvm_config.RELAY_LIST:
|
||||||
|
client.add_relay(relay)
|
||||||
|
client.connect()
|
||||||
|
|
||||||
|
nip89content = json.loads(dvm_config.NIP89.CONTENT)
|
||||||
|
if nip89content.get("name"):
|
||||||
|
name = nip89content.get("name")
|
||||||
|
about = nip89content.get("about")
|
||||||
|
image = nip89content.get("image")
|
||||||
|
|
||||||
|
|
||||||
|
# Set metadata
|
||||||
|
metadata = Metadata() \
|
||||||
|
.set_name(name) \
|
||||||
|
.set_display_name(name) \
|
||||||
|
.set_about(about) \
|
||||||
|
.set_picture(image) \
|
||||||
|
.set_lud16(lud16)
|
||||||
|
# .set_banner("https://example.com/banner.png") \
|
||||||
|
# .set_nip05("username@example.com") \
|
||||||
|
|
||||||
|
print(f"Setting profile metadata for {keys.public_key().to_bech32()}...")
|
||||||
|
print(metadata.as_json())
|
||||||
|
client.set_metadata(metadata)
|
||||||
|
client.disconnect()
|
||||||
|
|
||||||
|
|
||||||
|
def check_and_set_private_key(identifier):
|
||||||
|
if not os.getenv("DVM_PRIVATE_KEY_" + identifier.upper()):
|
||||||
|
pk = Keys.generate().secret_key().to_hex()
|
||||||
|
add_pk_to_env_file("DVM_PRIVATE_KEY_" + identifier.upper(), pk)
|
||||||
|
return pk
|
||||||
|
else:
|
||||||
|
return os.getenv("DVM_PRIVATE_KEY_" + identifier.upper())
|
||||||
|
|
||||||
|
|
||||||
|
def add_pk_to_env_file(dtag, oskey):
|
||||||
|
env_path = Path('.env')
|
||||||
|
if env_path.is_file():
|
||||||
|
print(f'loading environment from {env_path.resolve()}')
|
||||||
|
dotenv.load_dotenv(env_path, verbose=True, override=True)
|
||||||
|
dotenv.set_key(env_path, dtag, oskey)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_private_key():
|
||||||
|
return Keys.generate()
|
||||||
|
Reference in New Issue
Block a user