adding nip98, nostr.build account, convert tts to mp3 before upload

This commit is contained in:
Believethehype 2024-06-28 00:01:45 +02:00
parent 62cb455528
commit b8ebdddcb3
15 changed files with 81 additions and 22 deletions

View File

@ -18,6 +18,7 @@ REPLICATE_API_TOKEN = "" #API Key to run models on replicate.com
HUGGINGFACE_EMAIL = ""
HUGGINGFACE_PASSWORD = ""
COINSTATSOPENAPI_KEY = ""
NOSTR_BUILD_ACCOUNT_PK = "" # Enter the private key of an account you use with nostr.build
# 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.

View File

@ -88,7 +88,7 @@ def check_server_status(jobID, address) -> str | pd.DataFrame:
if content_type == "image/jpeg":
image = Image.open(io.BytesIO(response.content))
image.save("./outputs/image.jpg")
result = upload_media_to_hoster("./outputs/image.jpg")
result = asyncio.run(upload_media_to_hoster("./outputs/image.jpg"))
os.remove("./outputs/image.jpg")
return result
elif content_type == 'video/mp4':
@ -97,7 +97,7 @@ def check_server_status(jobID, address) -> str | pd.DataFrame:
f.close()
clip = VideoFileClip("./outputs/video.mp4")
clip.write_videofile("./outputs/video2.mp4")
result = upload_media_to_hoster("./outputs/video2.mp4")
result = asyncio.run(upload_media_to_hoster("./outputs/video2.mp4"))
clip.close()
os.remove("./outputs/video.mp4")
os.remove("./outputs/video2.mp4")

View File

@ -72,7 +72,7 @@ class MediaConverter(DVMTaskInterface):
async def process(self, request_form):
options = self.set_options(request_form)
url = upload_media_to_hoster(options["filepath"])
url = await upload_media_to_hoster(options["filepath"])
return url

View File

@ -112,7 +112,7 @@ class ImageGenerationDALLE(DVMTaskInterface):
response = requests.get(image_url)
image = Image.open(BytesIO(response.content)).convert("RGB")
image.save("./outputs/image.jpg")
result = upload_media_to_hoster("./outputs/image.jpg")
result = await upload_media_to_hoster("./outputs/image.jpg")
return result
except Exception as e:

View File

@ -107,7 +107,7 @@ class ImageGenerationReplicateSDXL(DVMTaskInterface):
response = requests.get(output[0])
image = Image.open(BytesIO(response.content)).convert("RGB")
image.save("./outputs/image.jpg")
result = upload_media_to_hoster("./outputs/image.jpg")
result = await upload_media_to_hoster("./outputs/image.jpg")
return result
except Exception as e:

View File

@ -136,7 +136,7 @@ class ImageGenerationMLX(DVMTaskInterface):
# Save them to disc
image = Image.fromarray(x.__array__())
image.save("./outputs/image.jpg")
result = upload_media_to_hoster("./outputs/image.jpg")
result = await upload_media_to_hoster("./outputs/image.jpg")
return result
except Exception as e:

View File

@ -1,8 +1,10 @@
import json
import os
import ffmpegio
from nostr_sdk import Kind
from nostr_dvm.utils.mediasource_utils import organize_input_media_data
from nostr_dvm.utils.nip88_utils import NIP88Config
os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
@ -37,6 +39,7 @@ class TextToSpeech(DVMTaskInterface):
async def init_dvm(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88config: NIP88Config = None,
admin_config: AdminConfig = None, options=None):
dvm_config.SCRIPT = os.path.abspath(__file__)
self.dvm_config = dvm_config
async def is_input_supported(self, tags, client=None, dvm_config=None):
for tag in tags:
@ -132,8 +135,14 @@ class TextToSpeech(DVMTaskInterface):
tts.tts_to_file(
text=text_clean,
speaker_wav=options["input_wav"], language=options["language"], file_path="outputs/output.mp3")
result = upload_media_to_hoster("outputs/output.mp3")
speaker_wav=options["input_wav"], language=options["language"], file_path="outputs/output.wav")
print("Converting Audio")
final_filename = "outputs/output.mp3"
fs, x = ffmpegio.audio.read("outputs/output.wav", sample_fmt='dbl', ac=1)
ffmpegio.audio.write(final_filename, fs, x, overwrite=True)
result = await upload_media_to_hoster(final_filename, dvm_config=self.dvm_config)
print(result)
return result
except Exception as e:

View File

@ -99,7 +99,7 @@ class VideoGenerationReplicateSVD(DVMTaskInterface):
print(output)
urllib.request.urlretrieve(output, "./outputs/svd.mp4")
result = upload_media_to_hoster("./outputs/svd.mp4")
result = await upload_media_to_hoster("./outputs/svd.mp4")
return result
except Exception as e:

View File

@ -6,7 +6,6 @@ from nostr_dvm.utils.nip88_utils import NIP88Config
from nostr_dvm.utils.nip89_utils import NIP89Config
from nostr_dvm.utils.nostr_utils import check_and_set_private_key
from nostr_dvm.utils.outbox_utils import AVOID_OUTBOX_RELAY_LIST
from nostr_dvm.utils.output_utils import PostProcessFunctionType
from nostr_dvm.utils.zap_utils import check_and_set_ln_bits_keys
class DVMConfig:
@ -31,7 +30,7 @@ class DVMConfig:
RELAY_TIMEOUT = 5
RELAY_LONG_TIMEOUT = 30
EXTERNAL_POST_PROCESS_TYPE = PostProcessFunctionType.NONE # Leave this on None, except the DVM is external
EXTERNAL_POST_PROCESS_TYPE = 0 # Leave this on None, except the DVM is external
LNBITS_INVOICE_KEY = '' # Will all automatically generated by default, or read from .env
LNBITS_ADMIN_KEY = '' # In order to pay invoices, e.g. from the bot to DVMs, or reimburse users.
LNBITS_URL = 'https://lnbits.com'
@ -42,8 +41,8 @@ class DVMConfig:
DB: str
NEW_USER_BALANCE: int = 0 # Free credits for new users
SUBSCRIPTION_MANAGEMENT = 'https://noogle.lol/discovery'
NIP88: NIP88Config
NIP89: NIP89Config
NIP88: NIP88Config = NIP88Config()
NIP89: NIP89Config = NIP89Config()
SEND_FEEDBACK_EVENTS = True
SHOW_RESULT_BEFORE_PAYMENT: bool = False # if this is true show results even when not paid right after autoprocess
SCHEDULE_UPDATES_SECONDS = 0

View File

@ -31,9 +31,9 @@ async def nip89_announce_tasks(dvm_config, client):
keys = Keys.parse(dvm_config.NIP89.PK)
content = dvm_config.NIP89.CONTENT
event = EventBuilder(EventDefinitions.KIND_ANNOUNCEMENT, content, [k_tag, d_tag]).to_event(keys)
evenid = await send_event(event, client=client, dvm_config=dvm_config)
eventid = await send_event(event, client=client, dvm_config=dvm_config)
print(bcolors.BLUE + "[" + dvm_config.NIP89.NAME + "] Announced NIP 89 for " + dvm_config.NIP89.NAME +" (" + evenid.to_hex() +")" + bcolors.ENDC)
print(bcolors.BLUE + "[" + dvm_config.NIP89.NAME + "] Announced NIP 89 for " + dvm_config.NIP89.NAME +" (" + eventid.to_hex() +")" + bcolors.ENDC)

View File

@ -0,0 +1,20 @@
import base64
import hashlib
from nostr_sdk import EventBuilder, Tag, Kind, Keys
def sha256sum(filename):
with open(filename, 'rb', buffering=0) as f:
return hashlib.file_digest(f, 'sha256').hexdigest()
async def generate_nip98_header(filepath, dvm_config):
keys = Keys.parse(dvm_config.NIP89.PK)
utag = Tag.parse(["u", "https://nostr.build/api/v2/upload/files"])
methodtag = Tag.parse(["method", "POST"])
payloadtag = Tag.parse(["payload", sha256sum(filepath)])
event = EventBuilder(Kind(27235), "", [utag, methodtag, payloadtag]).to_event(keys)
encoded_nip98_event = base64.b64encode(event.as_json().encode('utf-8')).decode('utf-8')
return "Nostr " + encoded_nip98_event

View File

@ -6,11 +6,14 @@ from types import NoneType
import emoji
import requests
from nostr_sdk import Tag, PublicKey, EventId
from nostr_sdk import Tag, PublicKey, EventId, Keys
from pyupload.uploader import CatboxUploader
import pandas
from nostr_dvm.utils.dvmconfig import DVMConfig
from nostr_dvm.utils.nip98_utils import generate_nip98_header
'''
Post process results to either given output format or a Nostr readable plain text.
'''
@ -146,26 +149,35 @@ Will probably need to switch to another system in the future.
'''
def upload_media_to_hoster(filepath: str):
async def upload_media_to_hoster(filepath: str, dvm_config=None, usealternativeforlargefiles=True):
if dvm_config is None:
dvm_config = DVMConfig()
dvm_config.NIP89.PK = Keys.parse(os.getenv("NOSTR_BUILD_ACCOUNT_PK")).secret_key().to_hex()
print("Uploading image: " + filepath)
try:
files = {'file': open(filepath, 'rb')}
file_stats = os.stat(filepath)
sizeinmb = file_stats.st_size / (1024 * 1024)
print("Filesize of Uploaded media: " + str(sizeinmb) + " Mb.")
if sizeinmb > 25:
if sizeinmb > 25 and usealternativeforlargefiles:
print("Filesize over Nostr.build limited, using catbox")
uploader = CatboxUploader(filepath)
result = uploader.execute()
return result
else:
url = 'https://nostr.build/api/v2/upload/files'
response = requests.post(url, files=files)
auth = await generate_nip98_header(filepath, dvm_config)
headers = {'authorization': auth}
response = requests.post(url, files=files, headers=headers)
print(response.text)
json_object = json.loads(response.text)
result = json_object["data"][0]["url"]
return result
except Exception as e:
print(e)
try:
uploader = CatboxUploader(filepath)
result = uploader.execute()

View File

@ -1,6 +1,6 @@
from setuptools import setup, find_packages
VERSION = '0.6.29'
VERSION = '0.6.30'
DESCRIPTION = 'A framework to build and run Nostr NIP90 Data Vending Machines'
LONG_DESCRIPTION = ('A framework to build and run Nostr NIP90 Data Vending Machines. See the github repository for more information')

View File

@ -22,7 +22,7 @@ if __name__ == '__main__':
dvm_config = build_default_config(identifier)
dvm_config.USE_OWN_VENV = True
dvm_config.FIX_COST = 0
dvm_config.PER_UNIT_COST = 0.2
dvm_config.PER_UNIT_COST = 0.1
admin_config_tts.LUD16 = dvm_config.LN_ADDRESS
# use an alternative local wav file you want to use for cloning
options = {'input_file': ""}

View File

@ -1,3 +1,21 @@
import asyncio
import os
from pathlib import Path
import dotenv
from nostr_sdk import Keys
from nostr_dvm.utils.output_utils import upload_media_to_hoster
upload_media_to_hoster("tests/output.wav")
if __name__ == '__main__':
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)
else:
raise FileNotFoundError(f'.env file not found at {env_path} ')
asyncio.run(upload_media_to_hoster("tests/output.wav"))
# asyncio.run(upload_media_to_hoster("tests/test.jpeg", dvm_config))