manual sync by default: sync now button, auto-sync toggle
This commit is contained in:
parent
857c9c85a1
commit
cd2d68a180
2 changed files with 62 additions and 3 deletions
|
|
@ -211,6 +211,7 @@ class ForumHandlers:
|
||||||
f'{search_form}'
|
f'{search_form}'
|
||||||
f' <a class="forum-action" href="/forum/new">+ new</a>'
|
f' <a class="forum-action" href="/forum/new">+ new</a>'
|
||||||
f' <a class="forum-action" href="/forum/moderation">mod</a>'
|
f' <a class="forum-action" href="/forum/moderation">mod</a>'
|
||||||
|
f' <a class="forum-action" href="/forum/sync/now">sync now</a>'
|
||||||
f' {muted_link}'
|
f' {muted_link}'
|
||||||
f"</div>"
|
f"</div>"
|
||||||
f"<p class=\"meta\">{total} threads{new_label}</p>"
|
f"<p class=\"meta\">{total} threads{new_label}</p>"
|
||||||
|
|
@ -502,16 +503,26 @@ class ForumHandlers:
|
||||||
|
|
||||||
auto_discover = self.fdb.get_setting("forum_auto_discover", "1")
|
auto_discover = self.fdb.get_setting("forum_auto_discover", "1")
|
||||||
auto_discover_checked = " checked" if auto_discover == "1" else ""
|
auto_discover_checked = " checked" if auto_discover == "1" else ""
|
||||||
|
auto_sync = self.fdb.get_setting("forum_auto_sync", "0")
|
||||||
|
auto_sync_checked = " checked" if auto_sync == "1" else ""
|
||||||
retention_days = self.fdb.get_setting("forum_retention_days", "30")
|
retention_days = self.fdb.get_setting("forum_retention_days", "30")
|
||||||
|
|
||||||
return self._respond(
|
return self._respond(
|
||||||
f"<h1>forum moderation</h1>"
|
f"<h1>forum moderation</h1>"
|
||||||
f"<p>{msg}</p>"
|
f"<p>{msg}</p>"
|
||||||
|
f'<p><a class="forum-action" href="/forum/sync/now">sync now</a></p>'
|
||||||
f"<h2>auto-discovery</h2>"
|
f"<h2>auto-discovery</h2>"
|
||||||
f'<form method="post" action="/forum/auto_discover">'
|
f'<form method="post" action="/forum/auto_discover">'
|
||||||
f'{self._csrf_field()}'
|
f'{self._csrf_field()}'
|
||||||
f'<label><input type="checkbox" name="enabled" value="1"{auto_discover_checked}>'
|
f'<label><input type="checkbox" name="enabled" value="1"{auto_discover_checked}>'
|
||||||
f" automatically discover and sync with other forum instances on the mesh</label><br><br>"
|
f" automatically discover other forum instances on the mesh</label><br><br>"
|
||||||
|
f'<button>save</button>'
|
||||||
|
f"</form>"
|
||||||
|
f"<h2>auto-sync</h2>"
|
||||||
|
f'<form method="post" action="/forum/auto_sync">'
|
||||||
|
f'{self._csrf_field()}'
|
||||||
|
f'<label><input type="checkbox" name="enabled" value="1"{auto_sync_checked}>'
|
||||||
|
f" automatically sync content every 5 minutes</label><br><br>"
|
||||||
f'<button>save</button>'
|
f'<button>save</button>'
|
||||||
f"</form>"
|
f"</form>"
|
||||||
f"<h2>storage</h2>"
|
f"<h2>storage</h2>"
|
||||||
|
|
@ -606,6 +617,22 @@ class ForumHandlers:
|
||||||
self.fdb.set_setting("forum_retention_days", str(days))
|
self.fdb.set_setting("forum_retention_days", str(days))
|
||||||
return self.handle_moderation(f"Storage retention set to {days} days.")
|
return self.handle_moderation(f"Storage retention set to {days} days.")
|
||||||
|
|
||||||
|
def handle_auto_sync(self, body):
|
||||||
|
enabled = "1" if body.get("enabled") else "0"
|
||||||
|
self.fdb.set_setting("forum_auto_sync", enabled)
|
||||||
|
if self.sync:
|
||||||
|
self.sync.set_auto_sync(enabled == "1")
|
||||||
|
return self.handle_moderation(f"Auto-sync {'enabled' if enabled == '1' else 'disabled'}.")
|
||||||
|
|
||||||
|
def handle_sync_now(self):
|
||||||
|
if not self.sync:
|
||||||
|
return self._respond("<p>Sync not available.</p>")
|
||||||
|
count = self.sync.sync_now()
|
||||||
|
msg = f"Synced with {count} instance{'s' if count != 1 else ''}."
|
||||||
|
if count == 0:
|
||||||
|
msg = "No peers to sync with."
|
||||||
|
return self._respond(f"<p>{msg}</p><p><a href=\"/forum\">back to forum</a></p>")
|
||||||
|
|
||||||
def handle_sync_add(self, body):
|
def handle_sync_add(self, body):
|
||||||
instance = body.get("instance", [""])[0].strip().replace("<", "").replace(">", "")
|
instance = body.get("instance", [""])[0].strip().replace("<", "").replace(">", "")
|
||||||
name = body.get("name", [""])[0].strip()
|
name = body.get("name", [""])[0].strip()
|
||||||
|
|
@ -744,6 +771,8 @@ class ForumHandlers:
|
||||||
return self._with_csrf(self.handle_unmute(sub[8:]), csrf_token)
|
return self._with_csrf(self.handle_unmute(sub[8:]), csrf_token)
|
||||||
elif sub.startswith("/blockhash/"):
|
elif sub.startswith("/blockhash/"):
|
||||||
return self._with_csrf(self.handle_block_hash(sub[11:]), csrf_token)
|
return self._with_csrf(self.handle_block_hash(sub[11:]), csrf_token)
|
||||||
|
elif sub == "/sync/now":
|
||||||
|
return self._with_csrf(self.handle_sync_now(), csrf_token)
|
||||||
elif method == "POST":
|
elif method == "POST":
|
||||||
if not self._check_csrf(body):
|
if not self._check_csrf(body):
|
||||||
return self._with_csrf(
|
return self._with_csrf(
|
||||||
|
|
@ -780,6 +809,8 @@ class ForumHandlers:
|
||||||
return self._with_csrf(self.handle_auto_discover(body), csrf_token)
|
return self._with_csrf(self.handle_auto_discover(body), csrf_token)
|
||||||
elif sub == "/storage":
|
elif sub == "/storage":
|
||||||
return self._with_csrf(self.handle_storage(body), csrf_token)
|
return self._with_csrf(self.handle_storage(body), csrf_token)
|
||||||
|
elif sub == "/auto_sync":
|
||||||
|
return self._with_csrf(self.handle_auto_sync(body), csrf_token)
|
||||||
|
|
||||||
return self._with_csrf(self._error(404), csrf_token)
|
return self._with_csrf(self._error(404), csrf_token)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,13 +55,41 @@ class ForumSync:
|
||||||
if self.fdb.get_setting("forum_auto_discover", "1") == "1":
|
if self.fdb.get_setting("forum_auto_discover", "1") == "1":
|
||||||
self._enable_announce_handler()
|
self._enable_announce_handler()
|
||||||
self._running = True
|
self._running = True
|
||||||
self._thread = threading.Thread(target=self._sync_loop, daemon=True)
|
if self.fdb.get_setting("forum_auto_sync", "0") == "1":
|
||||||
self._thread.start()
|
self._start_sync_loop()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self._running = False
|
self._running = False
|
||||||
self._disable_announce_handler()
|
self._disable_announce_handler()
|
||||||
|
|
||||||
|
def set_auto_sync(self, enabled):
|
||||||
|
self.fdb.set_setting("forum_auto_sync", "1" if enabled else "0")
|
||||||
|
if enabled:
|
||||||
|
self._start_sync_loop()
|
||||||
|
else:
|
||||||
|
pass # current cycle finishes, no new one starts
|
||||||
|
|
||||||
|
def sync_now(self):
|
||||||
|
"""Run one sync cycle immediately. Returns count of peers synced."""
|
||||||
|
instances = self.fdb.get_synced_instances()
|
||||||
|
random.shuffle(instances)
|
||||||
|
count = 0
|
||||||
|
for inst in instances[:GOSSIP_FANOUT]:
|
||||||
|
if not self._running:
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
self._sync_with(inst["instance_hash"])
|
||||||
|
count += 1
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[forum] sync error with {inst['instance_hash'][:16]}: {e}")
|
||||||
|
return count
|
||||||
|
|
||||||
|
def _start_sync_loop(self):
|
||||||
|
if self._thread and self._thread.is_alive():
|
||||||
|
return
|
||||||
|
self._thread = threading.Thread(target=self._sync_loop, daemon=True)
|
||||||
|
self._thread.start()
|
||||||
|
|
||||||
def set_auto_discover(self, enabled):
|
def set_auto_discover(self, enabled):
|
||||||
self.fdb.set_setting("forum_auto_discover", "1" if enabled else "0")
|
self.fdb.set_setting("forum_auto_discover", "1" if enabled else "0")
|
||||||
if enabled:
|
if enabled:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue