diff --git a/nostr_dvm/tasks/content_discovery_currently_popular.py b/nostr_dvm/tasks/content_discovery_currently_popular.py index 7b05e3c..d3dfc0b 100644 --- a/nostr_dvm/tasks/content_discovery_currently_popular.py +++ b/nostr_dvm/tasks/content_discovery_currently_popular.py @@ -92,7 +92,7 @@ def process(self, request_form): # if the dvm supports individual results, recalculate it every time for the request if self.personalized: return self.calculate_result(request_form) - #else return the result that gets updated once every schenduled update. In this case on database update. + # else return the result that gets updated once every scheduled update. In this case on database update. else: return self.result @@ -124,7 +124,9 @@ def calculate_result(self, request_form): ns.finallist = {} for event in events: if event.created_at().as_secs() > timestamp_hour_ago: - filt = Filter().kinds([definitions.EventDefinitions.KIND_ZAP, definitions.EventDefinitions.KIND_REPOST, definitions.EventDefinitions.KIND_REACTION, definitions.EventDefinitions.KIND_NOTE]).event(event.id()).since(lasthour) + filt = Filter().kinds([definitions.EventDefinitions.KIND_ZAP, definitions.EventDefinitions.KIND_REPOST, + definitions.EventDefinitions.KIND_REACTION, + definitions.EventDefinitions.KIND_NOTE]).event(event.id()).since(lasthour) reactions = cli.database().query([filt]) if len(reactions) >= self.min_reactions: ns.finallist[event.id().to_hex()] = len(reactions) @@ -132,7 +134,7 @@ def calculate_result(self, request_form): result_list = [] finallist_sorted = sorted(ns.finallist.items(), key=lambda x: x[1], reverse=True)[:int(options["max_results"])] for entry in finallist_sorted: - #print(EventId.parse(entry[0]).to_bech32() + "/" + EventId.parse(entry[0]).to_hex() + ": " + str(entry[1])) + # 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()) @@ -173,16 +175,19 @@ def sync_db(self): timestamp_hour_ago = Timestamp.now().as_secs() - self.db_since lasthour = Timestamp.from_secs(timestamp_hour_ago) - filter1 = Filter().kinds([definitions.EventDefinitions.KIND_NOTE, definitions.EventDefinitions.KIND_REACTION, definitions.EventDefinitions.KIND_ZAP]).since(lasthour) # Notes, reactions, zaps + filter1 = Filter().kinds([definitions.EventDefinitions.KIND_NOTE, definitions.EventDefinitions.KIND_REACTION, + definitions.EventDefinitions.KIND_ZAP]).since(lasthour) # 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.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) database.delete(Filter().until(Timestamp.from_secs( Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesnt get too full. - print("[" + self.dvm_config.IDENTIFIER + "] Done Syncing Notes of the last " + str(self.db_since) + " seconds..") + 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, @@ -277,9 +282,9 @@ def build_example_subscription(name, identifier, admin_config): admin_config.REBROADCAST_NIP89 = False admin_config.REBROADCAST_NIP88 = False - # admin_config.FETCH_NIP88 = True - # admin_config.EVENTID = "63a791cdc7bf78c14031616963105fce5793f532bb231687665b14fb6d805fdb" - # admin_config.PRIVKEY = dvm_config.PRIVATE_KEY + # admin_config.FETCH_NIP88 = True + # admin_config.EVENTID = "63a791cdc7bf78c14031616963105fce5793f532bb231687665b14fb6d805fdb" + # admin_config.PRIVKEY = dvm_config.PRIVATE_KEY return DicoverContentCurrentlyPopular(name=name, dvm_config=dvm_config, nip89config=nip89config, nip88config=nip88config, diff --git a/nostr_dvm/tasks/content_discovery_currently_popular_followers.py b/nostr_dvm/tasks/content_discovery_currently_popular_followers.py index 96ff616..876b114 100644 --- a/nostr_dvm/tasks/content_discovery_currently_popular_followers.py +++ b/nostr_dvm/tasks/content_discovery_currently_popular_followers.py @@ -111,7 +111,7 @@ def process(self, request_form): user = PublicKey.parse(options["user"]) followers_filter = Filter().author(user).kinds([Kind(3)]) followers = cli.get_events_of([followers_filter], timedelta(seconds=self.dvm_config.RELAY_TIMEOUT)) - print(followers) + #print(followers) # Negentropy reconciliation # Query events from database @@ -129,7 +129,7 @@ def process(self, request_form): newest = entry.created_at().as_secs() best_entry = entry - print(best_entry.as_json()) + #print(best_entry.as_json()) followings = [] for tag in best_entry.tags(): if tag.as_vec()[0] == "p": @@ -199,13 +199,13 @@ def sync_db(self): definitions.EventDefinitions.KIND_ZAP]).since(lasthour) # Notes, reactions, zaps # filter = Filter().author(keys.public_key()) - print("Syncing Notes.. this might take a while..") + 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) database.delete(Filter().until(Timestamp.from_secs( Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesnt get too full. - print("Done Syncing Notes of Last hour.") + 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, diff --git a/nostr_dvm/tasks/content_discovery_currently_popular_topic.py b/nostr_dvm/tasks/content_discovery_currently_popular_topic.py index f9d762c..52e6750 100644 --- a/nostr_dvm/tasks/content_discovery_currently_popular_topic.py +++ b/nostr_dvm/tasks/content_discovery_currently_popular_topic.py @@ -43,7 +43,8 @@ def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88c 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) + # 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, @@ -54,11 +55,10 @@ def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88c 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) + #print(self.search_list) if self.options.get("avoid_list"): self.avoid_list = self.options.get("avoid_list") if self.options.get("must_list"): @@ -93,7 +93,6 @@ def create_request_from_nostr_event(self, event, client=None, dvm_config=None): request_form = {"jobID": event.id().to_hex()} # default values - search = "" max_results = 200 for tag in event.tags(): @@ -114,7 +113,7 @@ def create_request_from_nostr_event(self, event, client=None, dvm_config=None): def process(self, request_form): # if the dvm supports individual results, recalculate it every time for the request if self.personalized: - return self.calculate_Result(request_form) + return self.calculate_result(request_form) #else return the result that gets updated once every schenduled update. In this case on database update. else: return self.result @@ -187,7 +186,7 @@ def schedule(self, dvm_config): self.sync_db() self.last_schedule = Timestamp.now().as_secs() self.result = self.calculate_result(self.request_form) - print(self.result) + #print(self.result) return 1 def sync_db(self): @@ -267,7 +266,6 @@ def build_example_subscription(name, identifier, admin_config, options, image, d dvm_config.SHOWLOG = True dvm_config.SCHEDULE_UPDATES_SECONDS = 600 # Every 10 minutes # Activate these to use a subscription based model instead - # dvm_config.SUBSCRIPTION_DAILY_COST = 1 dvm_config.FIX_COST = 0 # Add NIP89 diff --git a/nostr_dvm/tasks/discovery_trending_notes_nostrband.py b/nostr_dvm/tasks/discovery_trending_notes_nostrband.py index afab0bc..794de8b 100644 --- a/nostr_dvm/tasks/discovery_trending_notes_nostrband.py +++ b/nostr_dvm/tasks/discovery_trending_notes_nostrband.py @@ -71,7 +71,7 @@ def process(self, request_form): i += 1 if i < 20: e_tag = Tag.parse(["e", note["id"]]) - print(e_tag.as_vec()) + #print(e_tag.as_vec()) result_list.append(e_tag.as_vec()) else: break diff --git a/setup.py b/setup.py index ccc8067..66c6da0 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -VERSION = '0.3.5' +VERSION = '0.3.6' 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') diff --git a/tests/discovery.py b/tests/discovery.py index 0604789..3581fc7 100644 --- a/tests/discovery.py +++ b/tests/discovery.py @@ -6,7 +6,8 @@ from nostr_sdk import Keys from nostr_dvm.subscription import Subscription -from nostr_dvm.tasks import content_discovery_currently_popular, content_discovery_currently_popular_topic +from nostr_dvm.tasks import content_discovery_currently_popular, content_discovery_currently_popular_topic, \ + discovery_trending_notes_nostrband, content_discovery_currently_popular_followers from nostr_dvm.utils.admin_utils import AdminConfig from nostr_dvm.utils.backend_utils import keep_alive from nostr_dvm.utils.dvmconfig import DVMConfig @@ -20,15 +21,14 @@ def playground(): # 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.REBROADCAST_NIP89 = False - admin_config.UPDATE_PROFILE = False - # admin_config.DELETE_NIP89 = True - # admin_config.PRIVKEY = "" - # admin_config.EVENTID = "" - # 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() + # Popular Garden&Plants + admin_config_plants = AdminConfig() + admin_config_plants.REBROADCAST_NIP89 = False + admin_config_plants.UPDATE_PROFILE = False + # admin_config_plants.DELETE_NIP89 = True + # admin_config_plants.PRIVKEY = "" + # admin_config_plants.EVENTID = "" options_plants = { "search_list": ["garden", "gardening", "nature", " plants ", " plant ", " herb ", " herbs " " pine ", @@ -53,10 +53,14 @@ def playground(): description = "I show recent notes about plants and gardening" discovery_test_sub = content_discovery_currently_popular_topic.build_example("Garden & Growth", "discovery_content_garden", - admin_config, options_plants, image, + admin_config_plants, options_plants, image, description) discovery_test_sub.run() + # Popular Animals (Fluffy frens) + admin_config_animals = AdminConfig() + admin_config_animals.REBROADCAST_NIP89 = False + admin_config_animals.UPDATE_PROFILE = False options_animal = { "search_list": ["catstr", "pawstr", "dogstr", " cat ", " cats ", "🐾", "🐈", "🐕" , " dog ", " dogs ", " fluffy ", "animal", " duck", " lion ", " lions ", " fox ", " foxes ", " koala ", " koalas ", "capybara", "squirrel", "monkey", "panda", "alpaca", " otter"], @@ -79,16 +83,44 @@ def playground(): image = "https://image.nostr.build/f609311532c470f663e129510a76c9a1912ae9bc4aaaf058e5ba21cfb512c88e.jpg" description = "I show recent notes about animals" - discovery_test_sub2 = content_discovery_currently_popular_topic.build_example("Fluffy Frens", + discovery_animals = content_discovery_currently_popular_topic.build_example("Fluffy Frens", "discovery_content_fluffy", - admin_config, options_animal, image, + admin_config_animals, options_animal, image, description) - discovery_test_sub2.run() + discovery_animals.run() + + # Popular Followers + admin_config_followers = AdminConfig() + admin_config_followers.REBROADCAST_NIP89 = False + admin_config_followers.UPDATE_PROFILE = False + discovery_followers = content_discovery_currently_popular_followers.build_example("Currently Popular Notes from npubs you follow", + "discovery_content_followers", + admin_config_followers) + discovery_followers.run() + + #Popular Global + admin_config_global_popular = AdminConfig() + admin_config_global_popular.REBROADCAST_NIP89 = False + admin_config_global_popular.UPDATE_PROFILE = False + + discovery_global = content_discovery_currently_popular.build_example("Currently Popular Notes DVM", + "discovery_content_test", + admin_config_global_popular) + 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() + + + #Popular NOSTR.band + admin_config_trending_nostr_band = AdminConfig() + trending_nb = discovery_trending_notes_nostrband.build_example("Trending Notes on nostr.band", + "trending_notes_nostrband", admin_config_trending_nostr_band) + trending_nb.run() - # discovery_test = content_discovery_currently_popular.build_example("Currently Popular Notes DVM", - # "discovery_content_test", admin_config) - # discovery_test.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() @@ -98,8 +130,8 @@ def playground(): 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 - # x = threading.Thread(target=Subscription, args=(Subscription(subscription_config, sub_admin_config),)) - # x.start() + x = threading.Thread(target=Subscription, args=(Subscription(subscription_config, sub_admin_config),)) + x.start() # keep_alive()