mirror of
https://github.com/believethehype/nostrdvm.git
synced 2025-09-27 21:36:30 +02:00
content discovery: Option for non-individual results (to speed up results by updating the feed by scheduler))
This commit is contained in:
@@ -32,13 +32,29 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
|
|||||||
db_name = "db/nostr_default_recent_notes.db"
|
db_name = "db/nostr_default_recent_notes.db"
|
||||||
search_list = []
|
search_list = []
|
||||||
avoid_list = []
|
avoid_list = []
|
||||||
|
must_list = []
|
||||||
|
individual_result = False
|
||||||
|
result = ""
|
||||||
|
|
||||||
def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88config: NIP88Config = None,
|
def __init__(self, name, dvm_config: DVMConfig, nip89config: NIP89Config, nip88config: NIP88Config = None,
|
||||||
admin_config: AdminConfig = None, options=None):
|
admin_config: AdminConfig = None, options=None):
|
||||||
dvm_config.SCRIPT = os.path.abspath(__file__)
|
|
||||||
|
|
||||||
super().__init__(name=name, dvm_config=dvm_config, nip89config=nip89config, nip88config=nip88config,
|
super().__init__(name=name, dvm_config=dvm_config, nip89config=nip89config, nip88config=nip88config,
|
||||||
admin_config=admin_config, options=options)
|
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("individual_result"):
|
||||||
|
self.individual_result = bool(self.options.get("individual_result"))
|
||||||
|
|
||||||
self.last_schedule = Timestamp.now().as_secs()
|
self.last_schedule = Timestamp.now().as_secs()
|
||||||
if self.options.get("search_list"):
|
if self.options.get("search_list"):
|
||||||
self.search_list = self.options.get("search_list")
|
self.search_list = self.options.get("search_list")
|
||||||
@@ -58,6 +74,8 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
|
|||||||
init_logger(LogLevel.DEBUG)
|
init_logger(LogLevel.DEBUG)
|
||||||
|
|
||||||
self.sync_db()
|
self.sync_db()
|
||||||
|
if not self.individual_result:
|
||||||
|
self.result = self.calculate_Result(self.request_form)
|
||||||
|
|
||||||
def is_input_supported(self, tags, client=None, dvm_config=None):
|
def is_input_supported(self, tags, client=None, dvm_config=None):
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
@@ -76,7 +94,7 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
|
|||||||
|
|
||||||
# default values
|
# default values
|
||||||
search = ""
|
search = ""
|
||||||
max_results = 100
|
max_results = 200
|
||||||
|
|
||||||
for tag in event.tags():
|
for tag in event.tags():
|
||||||
if tag.as_vec()[0] == 'i':
|
if tag.as_vec()[0] == 'i':
|
||||||
@@ -90,9 +108,29 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
|
|||||||
"max_results": max_results,
|
"max_results": max_results,
|
||||||
}
|
}
|
||||||
request_form['options'] = json.dumps(options)
|
request_form['options'] = json.dumps(options)
|
||||||
|
self.request_form = request_form
|
||||||
return request_form
|
return request_form
|
||||||
|
|
||||||
def process(self, request_form):
|
def process(self, request_form):
|
||||||
|
# if the dvm supports individual results, recalculate it every time for the request
|
||||||
|
if self.individual_result:
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
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_users(result)
|
||||||
|
|
||||||
|
# if not text/plain, don't post-process
|
||||||
|
return result
|
||||||
|
def calculate_Result(self, request_form):
|
||||||
from nostr_sdk import Filter
|
from nostr_sdk import Filter
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
ns = SimpleNamespace()
|
ns = SimpleNamespace()
|
||||||
@@ -134,22 +172,12 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
|
|||||||
result_list = []
|
result_list = []
|
||||||
finallist_sorted = sorted(ns.finallist.items(), key=lambda x: x[1], reverse=True)[:int(options["max_results"])]
|
finallist_sorted = sorted(ns.finallist.items(), key=lambda x: x[1], reverse=True)[:int(options["max_results"])]
|
||||||
for entry in finallist_sorted:
|
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]])
|
e_tag = Tag.parse(["e", entry[0]])
|
||||||
result_list.append(e_tag.as_vec())
|
result_list.append(e_tag.as_vec())
|
||||||
print(len(result_list))
|
print(len(result_list))
|
||||||
return json.dumps(result_list)
|
return json.dumps(result_list)
|
||||||
|
|
||||||
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_users(result)
|
|
||||||
|
|
||||||
# if not text/plain, don't post-process
|
|
||||||
return result
|
|
||||||
|
|
||||||
def schedule(self, dvm_config):
|
def schedule(self, dvm_config):
|
||||||
if dvm_config.SCHEDULE_UPDATES_SECONDS == 0:
|
if dvm_config.SCHEDULE_UPDATES_SECONDS == 0:
|
||||||
@@ -158,6 +186,8 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
|
|||||||
if Timestamp.now().as_secs() >= self.last_schedule + dvm_config.SCHEDULE_UPDATES_SECONDS:
|
if Timestamp.now().as_secs() >= self.last_schedule + dvm_config.SCHEDULE_UPDATES_SECONDS:
|
||||||
self.sync_db()
|
self.sync_db()
|
||||||
self.last_schedule = Timestamp.now().as_secs()
|
self.last_schedule = Timestamp.now().as_secs()
|
||||||
|
self.result = self.calculate_Result(self.request_form)
|
||||||
|
print(self.result)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def sync_db(self):
|
def sync_db(self):
|
||||||
@@ -177,13 +207,13 @@ class DicoverContentCurrentlyPopularbyTopic(DVMTaskInterface):
|
|||||||
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())
|
# filter = Filter().author(keys.public_key())
|
||||||
print("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)
|
dbopts = NegentropyOptions().direction(NegentropyDirection.DOWN)
|
||||||
cli.reconcile(filter1, dbopts)
|
cli.reconcile(filter1, dbopts)
|
||||||
database.delete(Filter().until(Timestamp.from_secs(
|
database.delete(Filter().until(Timestamp.from_secs(
|
||||||
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
|
Timestamp.now().as_secs() - self.db_since))) # Clear old events so db doesn't get too full.
|
||||||
|
|
||||||
print("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,
|
# We build an example here that we can call by either calling this file directly from the main directory,
|
||||||
|
@@ -273,7 +273,7 @@ def nostr_client():
|
|||||||
# nostr_client_test_image("a beautiful purple ostrich watching the sunset")
|
# nostr_client_test_image("a beautiful purple ostrich watching the sunset")
|
||||||
# nostr_client_test_search_profile("dontbelieve")
|
# nostr_client_test_search_profile("dontbelieve")
|
||||||
wot = ["99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64"]
|
wot = ["99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64"]
|
||||||
nostr_client_test_disovery("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64", "7b7373dd58554ff4c0d28b401b9eae114bd92e30d872ae843b9a217375d66f9d")
|
nostr_client_test_disovery("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64", "a21592a70ef9a00695efb3f7e816e17742d251559aff154b16d063a408bcd74d")
|
||||||
#nostr_client_test_censor_filter(wot)
|
#nostr_client_test_censor_filter(wot)
|
||||||
#nostr_client_test_inactive_filter("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64")
|
#nostr_client_test_inactive_filter("99bb5591c9116600f845107d31f9b59e2f7c7e09a1ff802e84f1d43da557ca64")
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user