add paid outbox relays to avoid (to be continued..), fixes, better logging, add standalone updatedb dvm

This commit is contained in:
Believethehype 2024-06-04 20:15:20 +02:00
parent ba5377714e
commit 6210465df4
9 changed files with 401 additions and 78 deletions

View File

@ -138,7 +138,6 @@ class DicoverContentCurrentlyPopular(DVMTaskInterface):
if len(reactions) >= self.min_reactions:
ns.finallist[event.id().to_hex()] = len(reactions)
if len(ns.finallist) == 0:
cli.disconnect()
cli.shutdown()
return self.result
@ -148,9 +147,8 @@ class DicoverContentCurrentlyPopular(DVMTaskInterface):
# print(EventId.parse(entry[0]).to_bech32() + "/" + EventId.parse(entry[0]).to_hex() + ": " + str(entry[1]))
e_tag = Tag.parse(["e", entry[0]])
result_list.append(e_tag.as_vec())
cli.disconnect()
cli.shutdown()
print("[" + self.dvm_config.IDENTIFIER + "] Filtered " + str(
print("[" + self.dvm_config.NIP89.NAME + "] Filtered " + str(
len(result_list)) + " fitting events.")
return json.dumps(result_list)
@ -196,15 +194,15 @@ class DicoverContentCurrentlyPopular(DVMTaskInterface):
definitions.EventDefinitions.KIND_ZAP]).since(since) # Notes, reactions, zaps
# filter = Filter().author(keys.public_key())
print("[" + self.dvm_config.IDENTIFIER + "] Syncing notes of the last " + str(
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN)
cli.reconcile(filter1, dbopts)
database.delete(Filter().until(Timestamp.from_secs(
cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
cli.shutdown()
print(
"[" + self.dvm_config.IDENTIFIER + "] Done Syncing Notes of the last " + str(self.db_since) + " seconds..")
"[" + self.dvm_config.NIP89.NAME + "] Done Syncing Notes of the last " + str(self.db_since) + " seconds..")
# We build an example here that we can call by either calling this file directly from the main directory,

View File

@ -162,7 +162,7 @@ class DicoverContentCurrentlyPopularZaps(DVMTaskInterface):
e_tag = Tag.parse(["e", entry[0]])
result_list.append(e_tag.as_vec())
print("[" + self.dvm_config.IDENTIFIER + "] Filtered " + str(
print("[" + self.dvm_config.NIP89.NAME+ "] Filtered " + str(
len(result_list)) + " fitting events.")
cli.disconnect()
@ -216,15 +216,15 @@ class DicoverContentCurrentlyPopularZaps(DVMTaskInterface):
definitions.EventDefinitions.KIND_ZAP]).since(since) # Notes, reactions, zaps
# filter = Filter().author(keys.public_key())
print("[" + self.dvm_config.IDENTIFIER + "] Syncing notes of the last " + str(
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN)
cli.reconcile(filter1, dbopts)
database.delete(Filter().until(Timestamp.from_secs(
cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
cli.shutdown()
print(
"[" + self.dvm_config.IDENTIFIER + "] Done Syncing Notes of the last " + str(self.db_since) + " seconds..")
"[" + self.dvm_config.NIP89.NAME + "] Done Syncing Notes of the last " + str(self.db_since) + " seconds..")
# We build an example here that we can call by either calling this file directly from the main directory,

View File

@ -164,7 +164,7 @@ class DicoverContentCurrentlyPopularFollowers(DVMTaskInterface):
result_list.append(e_tag.as_vec())
cli.connect()
cli.shutdown()
print("[" + self.dvm_config.IDENTIFIER + "] Filtered " + str(
print("[" + self.dvm_config.NIP89.NAME + "] Filtered " + str(
len(result_list)) + " fitting events.")
return json.dumps(result_list)
@ -214,14 +214,14 @@ class DicoverContentCurrentlyPopularFollowers(DVMTaskInterface):
definitions.EventDefinitions.KIND_ZAP]).since(since) # Notes, reactions, zaps
# filter = Filter().author(keys.public_key())
print("[" + self.dvm_config.IDENTIFIER + "] Syncing notes of the last " + str(
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN)
cli.reconcile(filter1, dbopts)
database.delete(Filter().until(Timestamp.from_secs(
cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
cli.shutdown()
print("[" + self.dvm_config.IDENTIFIER + "] Done Syncing Notes of the last " + str(
print("[" + self.dvm_config.NIP89.NAME + "] Done Syncing Notes of the last " + str(
self.db_since) + " seconds..")

View File

@ -177,10 +177,8 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
e_tag = Tag.parse(["e", entry[0]])
result_list.append(e_tag.as_vec())
print("[" + self.dvm_config.IDENTIFIER + "] Filtered " + str(
print("[" + self.dvm_config.NIP89.NAME + "] Filtered " + str(
len(result_list)) + " fitting events.")
cli.disconnect()
cli.shutdown()
return json.dumps(result_list)
@ -218,13 +216,13 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
filter1 = Filter().kinds([definitions.EventDefinitions.KIND_NOTE, definitions.EventDefinitions.KIND_REACTION, definitions.EventDefinitions.KIND_ZAP]).since(since) # Notes, reactions, zaps
# filter = Filter().author(keys.public_key())
print("[" + self.dvm_config.IDENTIFIER + "] Syncing notes of the last " + str(self.db_since) + " seconds.. this might take a while..")
print("[" + self.dvm_config.NIP89.NAME + "] Syncing notes of the last " + str(self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN)
cli.reconcile(filter1, dbopts)
database.delete(Filter().until(Timestamp.from_secs(
cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
cli.shutdown()
print("[" + self.dvm_config.IDENTIFIER + "] Done Syncing Notes of the last " + str(self.db_since) + " seconds..")
print("[" + self.dvm_config.NIP89.NAME + "] Done Syncing Notes of the last " + str(self.db_since) + " seconds..")
# We build an example here that we can call by either calling this file directly from the main directory,

View File

@ -0,0 +1,269 @@
import json
import os
from datetime import timedelta
from nostr_sdk import Client, Timestamp, PublicKey, Tag, Keys, Options, SecretKey, NostrSigner, NostrDatabase, \
ClientBuilder, Filter, NegentropyOptions, NegentropyDirection, init_logger, LogLevel, Event, EventId, Kind
from nostr_dvm.interfaces.dvmtaskinterface import DVMTaskInterface, process_venv
from nostr_dvm.utils import definitions
from nostr_dvm.utils.admin_utils import AdminConfig
from nostr_dvm.utils.definitions import EventDefinitions
from nostr_dvm.utils.dvmconfig import DVMConfig, build_default_config
from nostr_dvm.utils.nip88_utils import NIP88Config, check_and_set_d_tag_nip88, check_and_set_tiereventid_nip88
from nostr_dvm.utils.nip89_utils import NIP89Config, check_and_set_d_tag, create_amount_tag
from nostr_dvm.utils.output_utils import post_process_list_to_events
"""
This File contains a Module to update the database for content discovery dvms
Accepted Inputs: none
Outputs: A list of events
Params: None
"""
class DicoverContentDBUpdateScheduler(DVMTaskInterface):
KIND: Kind = EventDefinitions.KIND_NIP90_CONTENT_DISCOVERY
TASK: str = "update-db-on-schedule"
FIX_COST: float = 0
dvm_config: DVMConfig
last_schedule: int
min_reactions = 2
db_since = 10 * 3600
db_name = "db/nostr_default_recent_notes.db"
search_list = []
avoid_list = []
must_list = []
personalized = False
result = ""
def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88config: NIP88Config = None,
admin_config: AdminConfig = None, options=None):
super().__init__(name=name, dvm_config=dvm_config, nip89config=nip89config, nip88config=nip88config,
admin_config=admin_config, options=options)
# Generate Generic request form for dvms that provide generic results (e.g only a calculation per update,
# not per call)
self.request_form = {"jobID": "generic"}
opts = {
"max_results": 200,
}
self.request_form['options'] = json.dumps(opts)
dvm_config.SCRIPT = os.path.abspath(__file__)
if self.options.get("personalized"):
self.personalized = bool(self.options.get("personalized"))
self.last_schedule = Timestamp.now().as_secs()
if self.options.get("search_list"):
self.search_list = self.options.get("search_list")
# print(self.search_list)
if self.options.get("avoid_list"):
self.avoid_list = self.options.get("avoid_list")
if self.options.get("must_list"):
self.must_list = self.options.get("must_list")
if self.options.get("db_name"):
self.db_name = self.options.get("db_name")
if self.options.get("db_since"):
self.db_since = int(self.options.get("db_since"))
use_logger = False
if use_logger:
init_logger(LogLevel.DEBUG)
if self.dvm_config.UPDATE_DATABASE:
self.sync_db()
def is_input_supported(self, tags, client=None, dvm_config=None):
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 != "text":
return False
return True
def create_request_from_nostr_event(self, event, client=None, dvm_config=None):
self.dvm_config = dvm_config
request_form = {"jobID": event.id().to_hex()}
# default values
max_results = 200
for tag in event.tags():
if tag.as_vec()[0] == 'i':
input_type = tag.as_vec()[2]
elif tag.as_vec()[0] == 'param':
param = tag.as_vec()[1]
if param == "max_results": # check for param type
max_results = int(tag.as_vec()[2])
options = {
"max_results": max_results,
}
request_form['options'] = json.dumps(options)
self.request_form = request_form
return request_form
def process(self, request_form):
return "I don't return results, I just update the DB."
def post_process(self, result, event):
"""Overwrite the interface function to return a social client readable format, if requested"""
for tag in event.tags():
if tag.as_vec()[0] == 'output':
format = tag.as_vec()[1]
if format == "text/plain": # check for output type
result = post_process_list_to_events(result)
# if not text/plain, don't post-process
return result
def schedule(self, dvm_config):
if dvm_config.SCHEDULE_UPDATES_SECONDS == 0:
return 0
else:
if Timestamp.now().as_secs() >= self.last_schedule + dvm_config.SCHEDULE_UPDATES_SECONDS:
if self.dvm_config.UPDATE_DATABASE:
self.sync_db()
self.last_schedule = Timestamp.now().as_secs()
return 1
def sync_db(self):
opts = (Options().wait_for_send(False).send_timeout(timedelta(seconds=self.dvm_config.RELAY_LONG_TIMEOUT)))
sk = SecretKey.from_hex(self.dvm_config.PRIVATE_KEY)
keys = Keys.parse(sk.to_hex())
signer = NostrSigner.keys(keys)
database = NostrDatabase.sqlite(self.db_name)
cli = ClientBuilder().signer(signer).database(database).opts(opts).build()
for relay in self.dvm_config.RECONCILE_DB_RELAY_LIST:
cli.add_relay(relay)
cli.connect()
timestamp_since = Timestamp.now().as_secs() - self.db_since
since = Timestamp.from_secs(timestamp_since)
filter1 = Filter().kinds([definitions.EventDefinitions.KIND_NOTE, definitions.EventDefinitions.KIND_REACTION,
definitions.EventDefinitions.KIND_ZAP]).since(since) # Notes, reactions, zaps
# filter = Filter().author(keys.public_key())
print("[" + self.dvm_config.IDENTIFIER + "] Syncing notes of the last " + str(
self.db_since) + " seconds.. this might take a while..")
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN)
cli.reconcile(filter1, dbopts)
cli.database().delete(Filter().until(Timestamp.from_secs(
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
cli.shutdown()
print(
"[" + self.dvm_config.IDENTIFIER + "] Done Syncing Notes of the last " + str(self.db_since) + " seconds..")
# We build an example here that we can call by either calling this file directly from the main directory,
# or by adding it to our playground. You can call the example and adjust it to your needs or redefine it in the
# playground or elsewhere
def build_example(name, identifier, admin_config, options, image, description, update_rate=600, cost=0,
processing_msg=None, update_db=True):
dvm_config = build_default_config(identifier)
dvm_config.USE_OWN_VENV = False
dvm_config.SHOWLOG = True
dvm_config.SCHEDULE_UPDATES_SECONDS = update_rate # Every 10 minutes
dvm_config.UPDATE_DATABASE = update_db
# Activate these to use a subscription based model instead
# dvm_config.SUBSCRIPTION_REQUIRED = True
# dvm_config.SUBSCRIPTION_DAILY_COST = 1
dvm_config.FIX_COST = cost
dvm_config.CUSTOM_PROCESSING_MESSAGE = processing_msg
admin_config.LUD16 = dvm_config.LN_ADDRESS
# Add NIP89
nip89info = {
"name": name,
"image": image,
"picture": image,
"about": description,
"lud16": dvm_config.LN_ADDRESS,
"encryptionSupported": True,
"cashuAccepted": True,
"personalized": False,
"amount": create_amount_tag(cost),
"nip90Params": {
"max_results": {
"required": False,
"values": [],
"description": "The number of maximum results to return (default currently 100)"
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return DicoverContentDBUpdateScheduler(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
def build_example_subscription(name, identifier, admin_config, options, image, description, processing_msg=None,
update_db=True):
dvm_config = build_default_config(identifier)
dvm_config.USE_OWN_VENV = False
dvm_config.SHOWLOG = True
dvm_config.SCHEDULE_UPDATES_SECONDS = 600 # Every 10 minutes
dvm_config.UPDATE_DATABASE = update_db
# Activate these to use a subscription based model instead
dvm_config.FIX_COST = 0
dvm_config.CUSTOM_PROCESSING_MESSAGE = processing_msg
admin_config.LUD16 = dvm_config.LN_ADDRESS
# Add NIP89
nip89info = {
"name": name,
"image": image,
"picture": image,
"about": description,
"lud16": dvm_config.LN_ADDRESS,
"encryptionSupported": True,
"cashuAccepted": True,
"subscription": True,
"personalized": False,
"nip90Params": {
"max_results": {
"required": False,
"values": [],
"description": "The number of maximum results to return (default currently 100)"
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
nip88config = NIP88Config()
nip88config.DTAG = check_and_set_d_tag_nip88(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip88config.TIER_EVENT = check_and_set_tiereventid_nip88(identifier, "1")
nip89config.NAME = name
nip88config.IMAGE = nip89info["image"]
nip88config.TITLE = name
nip88config.AMOUNT_DAILY = 100
nip88config.AMOUNT_MONTHLY = 2000
nip88config.CONTENT = "Subscribe to the DVM for unlimited use during your subscription"
nip88config.PERK1DESC = "Unlimited requests"
nip88config.PERK2DESC = "Support NostrDVM & NostrSDK development"
nip88config.PAYMENT_VERIFIER_PUBKEY = "5b5c045ecdf66fb540bdf2049fe0ef7f1a566fa427a4fe50d400a011b65a3a7e"
# admin_config.FETCH_NIP88 = True
# admin_config.EVENTID = "63a791cdc7bf78c14031616963105fce5793f532bb231687665b14fb6d805fdb"
# admin_config.PRIVKEY = dvm_config.PRIVATE_KEY
return DicoverContentDBUpdateScheduler(name=name, dvm_config=dvm_config, nip89config=nip89config,
nip88config=nip88config,
admin_config=admin_config,
options=options)
if __name__ == '__main__':
process_venv(DicoverContentDBUpdateScheduler)

View File

@ -25,10 +25,16 @@ class DVMConfig:
"wss://nostr.oxtr.dev", "wss://relay.nostr.bg",
"wss://relay.nostr.net" , "wss://relay.primal.net"] #, "wss://relay.snort.social"]
AVOID_PAID_OUTBOX_RELAY_LIST = ["wss://nostrelay.yeghro.site", "wss://nostr.wine",
"wss://nostr21.com", "wss://nostr.bitcoiner.social", "wss://nostr.orangepill.dev",
"wss://relay.lnpay.me", "wss://relay.snort.social", "wss://relay.minds.com/nostr/v1/ws",
"wss://nostr-pub.semisol.dev", "wss://mostr.pub", "wss://minds.com",
"wss://yabu.me", "wss://relay.yozora.world", "wss://filter.nostr.wine/?global=all", "wss://eden.nostr.land",
"wss://relay.orangepill.ovh", "wss://nostr.jcloud.es", "wss://af.purplerelay.com", "wss://za.purplerelay.com",
# cli.add_relay("wss://relay.primal.net")
]
#If a DVM has a paid subscription, overwrite list without the paid one.
#"wss://relay.damus.io"
RELAY_TIMEOUT = 5
RELAY_LONG_TIMEOUT = 30

View File

@ -123,11 +123,13 @@ def get_inbox_relays(event_to_send: Event, client: Client, dvm_config):
for tag in nip65event.tags():
if tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 2:
rtag = tag.as_vec()[1]
relays.append(rtag)
if rtag.rstrip("/") not in dvm_config.AVOID_PAID_OUTBOX_RELAY_LIST:
relays.append(rtag)
elif tag.as_vec()[0] == 'r' and len(tag.as_vec()) == 3:
if tag.as_vec()[2] == "read":
rtag = tag.as_vec()[1]
relays.append(rtag)
if rtag.rstrip("/") not in dvm_config.AVOID_PAID_OUTBOX_RELAY_LIST:
relays.append(rtag)
return relays
@ -140,7 +142,8 @@ def send_event_outbox(event: Event, client, dvm_config) -> EventId:
if tag.as_vec()[0] == 'relays':
for index, param in enumerate(tag.as_vec()):
if index != 0:
relays.append(tag.as_vec()[index])
if tag.as_vec()[index].rstrip("/") not in dvm_config.AVOID_PAID_OUTBOX_RELAY_LIST:
relays.append(tag.as_vec()[index])
break

View File

@ -1,6 +1,6 @@
from setuptools import setup, find_packages
VERSION = '0.5.8'
VERSION = '0.5.9'
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

@ -6,6 +6,9 @@ from pathlib import Path
import dotenv
from nostr_sdk import init_logger, LogLevel, Keys, NostrLibrary
from nostr_dvm.tasks.content_discovery_update_db_only import DicoverContentDBUpdateScheduler
#os.environ["RUST_BACKTRACE"] = "full"
from nostr_dvm.subscription import Subscription
from nostr_dvm.tasks.content_discovery_currently_popular import DicoverContentCurrentlyPopular
from nostr_dvm.tasks.content_discovery_currently_popular_by_top_zaps import DicoverContentCurrentlyPopularZaps
@ -19,7 +22,7 @@ from nostr_dvm.utils.nostr_utils import check_and_set_private_key
from nostr_dvm.utils.zap_utils import check_and_set_ln_bits_keys
rebroadcast_NIP89 = False # Announce NIP89 on startup
rebroadcast_NIP65_Relay_List = True
rebroadcast_NIP65_Relay_List = False
update_profile = False
global_update_rate = 120 # set this high on first sync so db can fully sync before another process trys to.
@ -30,13 +33,57 @@ use_logger = True
if use_logger:
init_logger(LogLevel.INFO)
def build_db_scheduler(name, identifier, admin_config, options, image, description, update_rate=600, cost=0,
processing_msg=None, update_db=True):
dvm_config = build_default_config(identifier)
dvm_config.USE_OWN_VENV = False
dvm_config.SHOWLOG = True
dvm_config.SCHEDULE_UPDATES_SECONDS = update_rate # Every 10 minutes
dvm_config.UPDATE_DATABASE = update_db
# Activate these to use a subscription based model instead
# dvm_config.SUBSCRIPTION_REQUIRED = True
# dvm_config.SUBSCRIPTION_DAILY_COST = 1
dvm_config.FIX_COST = cost
dvm_config.CUSTOM_PROCESSING_MESSAGE = processing_msg
admin_config.LUD16 = dvm_config.LN_ADDRESS
# Add NIP89
nip89info = {
"name": name,
"image": image,
"picture": image,
"about": description,
"lud16": dvm_config.LN_ADDRESS,
"encryptionSupported": True,
"cashuAccepted": True,
"personalized": False,
"amount": create_amount_tag(cost),
"nip90Params": {
"max_results": {
"required": False,
"values": [],
"description": "The number of maximum results to return (default currently 100)"
}
}
}
nip89config = NIP89Config()
nip89config.DTAG = check_and_set_d_tag(identifier, name, dvm_config.PRIVATE_KEY, nip89info["image"])
nip89config.CONTENT = json.dumps(nip89info)
return DicoverContentDBUpdateScheduler(name=name, dvm_config=dvm_config, nip89config=nip89config,
admin_config=admin_config, options=options)
def build_example_nostrband(name, identifier, admin_config, image, about, custom_processing_msg):
dvm_config: DVMConfig = build_default_config(identifier)
dvm_config.USE_OWN_VENV = False
dvm_config.CUSTOM_PROCESSING_MESSAGE = custom_processing_msg
dvm_config.RELAY_LIST = ["wss://dvms.f7z.io",
"wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg"
]
#dvm_config.RELAY_LIST = ["wss://dvms.f7z.io",
# "wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg"
# ]
admin_config.LUD16 = dvm_config.LN_ADDRESS
# Add NIP89
@ -67,9 +114,9 @@ def build_example_topic(name, identifier, admin_config, options, image, descript
dvm_config.UPDATE_DATABASE = update_db
dvm_config.FIX_COST = cost
dvm_config.CUSTOM_PROCESSING_MESSAGE = processing_msg
dvm_config.RELAY_LIST = ["wss://dvms.f7z.io",
"wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg"
]
#dvm_config.RELAY_LIST = ["wss://dvms.f7z.io",
# "wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg"
# ]
admin_config.LUD16 = dvm_config.LN_ADDRESS
# Add NIP89
@ -111,9 +158,9 @@ def build_example_popular(name, identifier, admin_config, options, image, cost=0
#dvm_config.RELAY_LIST = ["wss://dvms.f7z.io", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg",
#"wss://relay.nostr.net"]
dvm_config.CUSTOM_PROCESSING_MESSAGE = processing_msg
dvm_config.RELAY_LIST = ["wss://dvms.f7z.io",
"wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg"
]
#dvm_config.RELAY_LIST = ["wss://dvms.f7z.io",
# "wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg"
# ]
admin_config.LUD16 = dvm_config.LN_ADDRESS
# Add NIP89
@ -152,9 +199,9 @@ def build_example_popular_followers(name, identifier, admin_config, options, ima
dvm_config.UPDATE_DATABASE = update_db
dvm_config.FIX_COST = cost
dvm_config.CUSTOM_PROCESSING_MESSAGE = processing_msg
dvm_config.RELAY_LIST = ["wss://dvms.f7z.io",
"wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg"
]
#dvm_config.RELAY_LIST = ["wss://dvms.f7z.io",
# "wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg"
# ]
admin_config.LUD16 = dvm_config.LN_ADDRESS
# Add NIP89
@ -196,9 +243,9 @@ def build_example_top_zapped(name, identifier, admin_config, options, image, cos
dvm_config.UPDATE_DATABASE = update_db
dvm_config.FIX_COST = cost
dvm_config.CUSTOM_PROCESSING_MESSAGE = processing_msg
dvm_config.RELAY_LIST = ["wss://dvms.f7z.io",
"wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg"
]
#dvm_config.RELAY_LIST = ["wss://dvms.f7z.io",
# "wss://nostr.mom", "wss://nostr.oxtr.dev", "wss://relay.nostr.bg"
# ]
admin_config.LUD16 = dvm_config.LN_ADDRESS
# Add NIP89
@ -233,6 +280,26 @@ def build_example_top_zapped(name, identifier, admin_config, options, image, cos
def playground():
#DB Scheduler, do not announce, just use it to update the DB for the other DVMs.
admin_config_db_scheduler= AdminConfig()
options_animal = {
"db_name": "db/nostr_recent_notes.db",
"db_since": 48 * 60 * 60, # 48h since gmt,
"personalized": False,
"logger": False}
image = ""
about = "I just update the Database based on my schedule"
db_scheduler = build_db_scheduler("DB Scheduler",
"db_scheduler",
admin_config_db_scheduler, options_animal,
image=image,
description=about,
update_rate=global_update_rate,
cost=0,
update_db=True)
db_scheduler.run()
# Popular top zapped
admin_config_top_zaps = AdminConfig()
admin_config_top_zaps.REBROADCAST_NIP89 = rebroadcast_NIP89
@ -264,6 +331,7 @@ def playground():
discovery_topzaps.run()
# Popular NOSTR.band
admin_config_trending_nostr_band = AdminConfig()
admin_config_trending_nostr_band.REBROADCAST_NIP89 = rebroadcast_NIP89
@ -330,7 +398,7 @@ def playground():
custom_processing_msg = ["Looking for fluffy frens...", "Let's see if we find some animals for you..",
"Looking for the goodest bois and girls.."]
cost = 0
update_db = True # As this is our largerst DB we update it here, and the other dvms use it. TODO make an own scheduler that only updates the db
update_db = False # As this is our largerst DB we update it here, and the other dvms use it. TODO make an own scheduler that only updates the db
discovery_animals = build_example_topic("Fluffy Frens",
"discovery_content_fluffy",
admin_config_animals, options_animal,
@ -348,10 +416,10 @@ def playground():
admin_config_plants.REBROADCAST_NIP89 = rebroadcast_NIP89
admin_config_plants.REBROADCAST_NIP65_RELAY_LIST = rebroadcast_NIP65_Relay_List
admin_config_plants.UPDATE_PROFILE = update_profile
#admin_config_plants.DELETE_NIP89 = True
#admin_config_plants.PRIVKEY = ""
#admin_config_plants.EVENTID = "ff28be59708ee597c7010fd43a7e649e1ab51da491266ca82a84177e0007e4d6"
#admin_config_plants.POW = True
# admin_config_plants.DELETE_NIP89 = True
# admin_config_plants.PRIVKEY = ""
# admin_config_plants.EVENTID = "ff28be59708ee597c7010fd43a7e649e1ab51da491266ca82a84177e0007e4d6"
# admin_config_plants.POW = True
options_plants = {
"search_list": ["garden", "gardening", "nature", " plants ", " plant ", " herb ", " herbs " " pine ",
"homesteading", "rosemary", "chicken", "🪻", "🌿", "☘️", "🌲", "flower", "forest", "watering",
@ -360,7 +428,8 @@ def playground():
"avoid_list": ["porn", "smoke", "nsfw", "bitcoin", "bolt12", "bolt11", "github", "currency", "utxo",
"encryption", "government", "airpod", "ipad", "iphone", "android", "warren",
"moderna", "pfizer", "corona", "socialism", "critical theory", "law of nature"
"murder", "tax", "engagement", "hodlers", "hodl", "gdp", "global markets", "crypto", "wherostr",
"murder", "tax", "engagement",
"hodlers", "hodl", "gdp", "global markets", "crypto", "wherostr",
"presidency", "dollar", "asset", "microsoft", "amazon", "billionaire", "ceo", "industry",
"white house", "blocks", "streaming", "summary", "wealth", "beef", "cunt", "nigger", "business",
"retail", "bakery", "synth", "slaughterhouse", "hamas", "dog days", "ww3", "socialmedia",
@ -379,7 +448,7 @@ def playground():
"Looking for #goodvibes..", "All I do is #blooming.."]
update_db = False
cost = 0
discovery_test_sub = build_example_topic("Garden & Growth", "discovery_content_garden",
discovery_garden = build_example_topic("Garden & Growth", "discovery_content_garden",
admin_config_plants, options_plants,
image=image,
description=description,
@ -387,18 +456,17 @@ def playground():
cost=cost,
processing_msg=custom_processing_msg,
update_db=update_db)
discovery_test_sub.run()
discovery_garden.run()
# Popular Followers
admin_config_followers = AdminConfig()
admin_config_followers.REBROADCAST_NIP89 = rebroadcast_NIP89
admin_config_followers.REBROADCAST_NIP65_RELAY_LIST = rebroadcast_NIP65_Relay_List
admin_config_followers.UPDATE_PROFILE = update_profile
#admin_config_followers.DELETE_NIP89 = True
#admin_config_followers.PRIVKEY = ""
#admin_config_followers.EVENTID = "590cd7b2902224f740acbd6845023a5ab4a959386184f3360c2859019cfd48fa"
#admin_config_followers.POW = True
# admin_config_followers.DELETE_NIP89 = True
# admin_config_followers.PRIVKEY = ""
# admin_config_followers.EVENTID = "590cd7b2902224f740acbd6845023a5ab4a959386184f3360c2859019cfd48fa"
# admin_config_followers.POW = True
custom_processing_msg = ["Processing popular notes from npubs you follow..",
"Let's see what npubs you follow have been up to..",
"Processing a personalized feed, just for you.."]
@ -427,10 +495,10 @@ def playground():
admin_config_global_popular.REBROADCAST_NIP89 = rebroadcast_NIP89
admin_config_global_popular.REBROADCAST_NIP65_RELAY_LIST = rebroadcast_NIP65_Relay_List
admin_config_global_popular.UPDATE_PROFILE = update_profile
#admin_config_global_popular.DELETE_NIP89 = True
#admin_config_global_popular.PRIVKEY = ""
#admin_config_global_popular.EVENTID = "2fea4ee2ccf0fa11db171113ffd7a676f800f34121478b7c9a4e73c2f1990028"
#admin_config_global_popular.POW = True
# admin_config_global_popular.DELETE_NIP89 = True
# admin_config_global_popular.PRIVKEY = ""
# admin_config_global_popular.EVENTID = "2fea4ee2ccf0fa11db171113ffd7a676f800f34121478b7c9a4e73c2f1990028"
# admin_config_global_popular.POW = True
custom_processing_msg = ["Looking for popular notes on the Nostr..", "Let's see what's trending on Nostr..",
"Finding the best notes on the Nostr.."]
update_db = False
@ -452,25 +520,6 @@ def playground():
update_db=update_db)
discovery_global.run()
# discovery_test_sub = content_discovery_currently_popular.build_example_subscription("Currently Popular Notes DVM (with Subscriptions)", "discovery_content_test", admin_config)
# discovery_test_sub.run()
# Subscription Manager DVM
# subscription_config = DVMConfig()
# subscription_config.PRIVATE_KEY = check_and_set_private_key("dvm_subscription")
# npub = Keys.parse(subscription_config.PRIVATE_KEY).public_key().to_bech32()
# invoice_key, admin_key, wallet_id, user_id, lnaddress = check_and_set_ln_bits_keys("dvm_subscription", npub)
# subscription_config.LNBITS_INVOICE_KEY = invoice_key
# subscription_config.LNBITS_ADMIN_KEY = admin_key # The dvm might pay failed jobs back
# subscription_config.LNBITS_URL = os.getenv("LNBITS_HOST")
# sub_admin_config = AdminConfig()
# sub_admin_config.USERNPUBS = ["7782f93c5762538e1f7ccc5af83cd8018a528b9cd965048386ca1b75335f24c6"] #Add npubs of services that can contact the subscription handler
# currently there is none, but add this once subscriptions are live.
# x = threading.Thread(target=Subscription, args=(Subscription(subscription_config, sub_admin_config),))
# x.start()
# keep_alive()
if __name__ == '__main__':