feat(kad): community ratings/comments for search results & shared files (#434) - #500
Merged
Merged
Conversation
This was referenced Jul 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
/search/resultsentry now carriescomments[]+kad_comment_search_running, and there are newGET/POST /api/v0/search/results/{hash}/commentsendpoints 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 ofCPartFile(downloads),CKnownFile(shared) andCSearchFile(search). So this is mostly reuse, not new machinery:RequestKadNoteSearch()moved up toCAbstractFile— one trigger for downloads, shared files and search results. Its guard now also accepts a file present in the current search list.Search.cpp: request-send, note-arrival, search-end) resolves the target hash against the search list too, so notes attach to theCSearchFileand the running flag clears on it.CPartFile*toCAbstractFile*, with the Kad-note reader lifted into a sharedCAbstractFile::GetKadNotesComments(). Same modal, same "Get from Kad" button, now reachable from a search-result menu and a shared file's details.CEC_SearchFile_Tagalready borrows theEC_TAG_PARTFILE_*tags, so the comments container + running flag ride those, and the existingEC_OP_SHARED_FILE_SEARCH_KAD_NOTEStrigger 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:m_FileRatingListcache +GetRatingAndCommentsnow live once onCAbstractFile, so downloads, shared files and search results share the same code;CEC_SharedFile_Tag), which — via the virtualGetRatingAndComments— covers both downloads and plain shared files, and decoded once inCKnownFilesRem::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 aCSearchFilesearch 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 ownCEntry::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. SoCEC_SearchFile_Tagsends 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~CSearchFilealso now firesSearchFileBeingDestroyed(it was empty) so a recreated result can't strand an open dialog.Renamed the JSON field
kad_search_running→kad_comment_search_runningon the download comments endpoint, thedownloadobject, and thedownload_updatedSSE 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
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:
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
amuledwon't understand the search-result trigger or serialize the notes back). The monolithic build uses local Kad directly.RequestKadNoteSearchguard message now mentions the search results as an eligible source.