Skip to content

feat(kad): community ratings/comments for search results & shared files (#434) - #500

Merged
got3nks merged 1 commit into
amule-org:masterfrom
got3nks:feat/kad-notes-search-results
Jul 16, 2026
Merged

feat(kad): community ratings/comments for search results & shared files (#434)#500
got3nks merged 1 commit into
amule-org:masterfrom
got3nks:feat/kad-notes-search-results

Conversation

@got3nks

@got3nks got3nks commented Jul 16, 2026

Copy link
Copy Markdown

Completes the first bullet of #434 — surfacing the community ratings/comments other users publish to Kad for a file you have not downloaded — which #462 explicitly deferred as "shared-file / search parity". eMule lets you right-click a search result, or open a shared file's details, and pull those notes on demand; aMule could only do it for files already in the download queue. This wires the read side end to end for search results and shared files, across the native GUI, the remote GUI (amulegui) and the REST/SSE API (amuleapi). danim7 flagged the gap on #462; this is the follow-up.

What you can do now

  • Monolithic GUI — "Show all comments" on a search-result right-click, and on a shared file's File Details, both open the existing comments dialog; its "Get from Kad" button runs the on-demand lookup and notes stream in.
  • amulegui — the same two entry points work against a remote daemon (the daemon owns Kad; the GUI triggers over EC and displays what streams back).
  • amuleapi — each /search/results entry now carries comments[] + kad_comment_search_running, and there are new GET/POST /api/v0/search/results/{hash}/comments endpoints mirroring the download ones.

How it works

A Kad NOTES lookup only needs a file's hash + size, both of which a search result and a shared file already have, and the notes are stored on CAbstractFile — the common base of CPartFile (downloads), CKnownFile (shared) and CSearchFile (search). So this is mostly reuse, not new machinery:

  • RequestKadNoteSearch() moved up to CAbstractFile — one trigger for downloads, shared files and search results. Its guard now also accepts a file present in the current search list.
  • Kad-note routing (Search.cpp: request-send, note-arrival, search-end) resolves the target hash against the search list too, so notes attach to the CSearchFile and the running flag clears on it.
  • The comments dialog is unchanged — widened from CPartFile* to CAbstractFile*, with the Kad-note reader lifted into a shared CAbstractFile::GetKadNotesComments(). Same modal, same "Get from Kad" button, now reachable from a search-result menu and a shared file's details.
  • No new EC ops or tagsCEC_SearchFile_Tag already borrows the EC_TAG_PARTFILE_* tags, so the comments container + running flag ride those, and the existing EC_OP_SHARED_FILE_SEARCH_KAD_NOTES trigger now resolves search-result hashes.

Unified rating/comment cache (amulegui)

Previously the amulegui-side rating list was duplicated on CPartFile (and, in this PR's early drafts, CSearchFile), and plain shared files had no cache and no comment serialization at all — so shared-file comments could never appear remotely. This PR collapses it to one implementation:

  • the m_FileRatingList cache + GetRatingAndComments now live once on CAbstractFile, so downloads, shared files and search results share the same code;
  • comments are serialized once on the shared-file base tag (CEC_SharedFile_Tag), which — via the virtual GetRatingAndComments — covers both downloads and plain shared files, and decoded once in CKnownFilesRem::ProcessItemUpdate.

One file, several objects, one hash

A file can exist locally as more than one object with the same ed2k hash at once — a downloading CPartFile (also shared) and a CSearchFile search hit. The Kad NOTES lookup is keyed by hash, so both the running-flag cleanup and the arriving notes are routed to every local match, not just the first one found. Without this, triggering the lookup from a search result for a file you're already downloading set the "running" flag on the search object but cleared it on the partfile — leaving the search result permanently stuck at "a note lookup is already running" — and the notes landed on the partfile's list instead of the search result's, so the search dialog stayed empty. Each target gets its own CEntry::Copy() so the note lists dedup independently.

The one amulegui subtlety worth calling out

Search results have no EC change-generation and their reply builder never resets the per-connection value-map on (re)creation (unlike the download path, which uses MarkECChanged + EraseValueMap). Left on the value-map, a result's comments container would be de-duplicated after a single send and never reach a result object the GUI created before the notes arrived. So CEC_SearchFile_Tag sends the comments without the value-map — gated on the built list, so idle results cost nothing. Downloads and shared files keep the efficient value-map path (their change-generation machinery makes it correct). The CLIENT_GUI ~CSearchFile also now fires SearchFileBeingDestroyed (it was empty) so a recreated result can't strand an open dialog.

⚠️ Breaking change (unreleased API)

Renamed the JSON field kad_search_runningkad_comment_search_running on the download comments endpoint, the download object, and the download_updated SSE event. The old name (shipped only on unreleased master) read as "a Kad search is running" — ambiguous against an actual Kad file search — whereas the flag only ever tracks a Kad notes/comments lookup. Both comment endpoints now use the clearer, consistent name.

Testing

  • All seven binaries build + link clean on macOS, Ubuntu and mingw-w64.
  • clang-format (v18), Tier-1 + Tier-2 clang-tidy, and po catalogs in sync.
  • Full amuleapi curl suite (29 scripts, ~980 assertions) green against a connected test node, including the new search-comments endpoints (POST trigger → 202 kad_search_started, GET → notes + flag) and the renamed download field.

Manual testing on the live Kad network — triggered a community-comments lookup from every entry point in both front ends and confirmed the notes appear:

Entry point Monolithic aMule amulegui (remote)
Downloads → Show all comments → Get from Kad
Shared files → File details → Show all comments
Search results → Show all comments → Get from Kad

Also verified the shared-hash case: triggering the lookup from a search result for a file already in the download queue no longer sticks on "a note lookup is already running", and the notes reach both that file's download dialog and its search-result dialog.

Notes for reviewers

  • This is a daemon-side feature: amulegui needs a daemon built from this branch (an older amuled won't understand the search-result trigger or serialize the notes back). The monolithic build uses local Kad directly.
  • One string changed: the RequestKadNoteSearch guard message now mentions the search results as an eligible source.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant