Opensuse fixes - #440
Merged
Merged
Conversation
ngosang
pushed a commit
to ngosang/amule
that referenced
this pull request
Jul 13, 2026
… + REST, and add remote GeoIP config (amule-project#439, amule-project#440) Resolves amule-project#439 (peer country) and amule-project#440 (server country). **Core refactor.** Move the GeoIP resolver (`CIP2Country`) out of the GUI and into the core (`CamuleApp`), headless, so `amuled` resolves country codes too. Flag rendering becomes a separate GUI concern (`CCountryFlags`, embedded PNGs) — no libmaxminddb needed to display. **amule-project#439 / amule-project#440.** Resolve each peer's and server's country core-side and expose the ISO code: over EC (`EC_TAG_CLIENT_COUNTRY`, `EC_TAG_SERVER_COUNTRY`); over REST as `country_code` on `/clients` and `/servers` (always present, empty when off/unresolved); and in amulecmd's `show servers` (e.g. `[de]`). The peer list renders the flag; unresolved peers show none. **Remote GeoIP config (amulegui).** amulegui has no resolver — it configures the daemon's GeoIP over EC: settings sync, live status line, "Update now", auto-download on source change, and the page is hidden when the connected core lacks GeoIP (built without it, or a pre-3.1 daemon). **Decoupling.** `ENABLE_IP2COUNTRY` now gates only the resolver (libmaxminddb); a new `GEOIP_GUI` gate (`ENABLE_IP2COUNTRY || CLIENT_GUI`) covers display + config, so amulegui shows flags and edits GeoIP config with no libmaxminddb linked. **REST `/preferences`.** New `ip2country` object (GET + PATCH: enabled, source, custom URL, MaxMind license, auto-update, `update_now`; plus read-only status + `supported`). Mixed builds (core off / GUI on and vice-versa) are link- and crash-safe. Tests: `RefresherTest`, curl (`05`, `10`), plus live macOS validation (monolithic + amulegui + amuled + amuleapi). Docs: `docs/api/REFERENCE.md`.
ngosang
added a commit
to ngosang/amule
that referenced
this pull request
Jul 29, 2026
… columns Surface `country_code` (amule-project#439/amule-project#440, added core-side in 5b7cdf1) in the Web UI as a plain 2-letter ISO 3166-1 alpha-2 code, no flag: a sortable country column in the peer table (Clients page + the per-file Clients tab of both detail panels) and in the ED2K server table. Its header is an abbreviation ("CC" in English, "CP" in Spanish) because a spelled-out "Country" would force ~80px for a 2-char cell. The column always renders. The daemon omits the EC tag entirely when GeoIP is off or the build lacks it, which reaches the REST layer as `country_code: ""` and shows as "—" like any other empty cell -- so nothing has to probe for GeoIP support (/status carries no GeoIP flag, and the Web UI has no preferences store to read `ip2country.supported` from). Also fills three gaps in the peer table -- fields /clients has always returned but nothing painted: Address (`ip:port`), OS (`os_info`) and User hash. All three start hidden in every consumer, so they only widen the table once picked from the column picker. Peer columns now run CC, Address, Name, User hash, Software, OS, File, so each identity field sits next to the one it qualifies. The four transfer totals are relabelled to the compact DL/UL total and DL/UL session, which also lets all four share one width. The server table is reordered to match (CC, Address, Name, Description, Users, Files, Version, Ping, Priority, Actions) and starts with Address, Version and Ping hidden, keeping the default view to what identifies a server and how busy it is. Description also drops its fixed 180px and splits the leftover width with Name, since descriptions are long (forum URLs, blurbs). Both tables' Name columns lose their `always` flag, so the picker offers them like any other column -- with Address and CC available, the name is no longer the only way to tell rows apart. Downloads / Shared / Search keep theirs pinned: there the name column anchors the row-selection checkbox. Two pre-existing bugs this surfaced, both fixed for every list view: * A header label wider than its column spilled over the neighbouring header instead of being clipped (`white-space: nowrap`, and no overflow rule of its own) -- which is why a "Country" label looked like it fit 70px. Headers now ellipsize and carry the full label as a title tooltip, so a translation that outgrows its column stays readable on hover. * The server Address column sorted its `ip:port` strings lexically, putting 10.x before 9.x and .182 before .87. Both tables now sort it by IP value through one shared `ipNum` helper in table.js, next to the other sort/filter helpers. Peer detail-only fields (GET /clients/{ecid}) are untouched: they need a peer detail panel, not a column.
ngosang
added a commit
to ngosang/amule
that referenced
this pull request
Jul 29, 2026
… columns (amule-project#690) Surface `country_code` (amule-project#439/amule-project#440, added core-side in 5b7cdf1) in the Web UI as a plain 2-letter ISO 3166-1 alpha-2 code, no flag: a sortable country column in the peer table (Clients page + the per-file Clients tab of both detail panels) and in the ED2K server table. Its header is an abbreviation ("CC" in English, "CP" in Spanish) because a spelled-out "Country" would force ~80px for a 2-char cell. The column always renders. The daemon omits the EC tag entirely when GeoIP is off or the build lacks it, which reaches the REST layer as `country_code: ""` and shows as "—" like any other empty cell -- so nothing has to probe for GeoIP support (/status carries no GeoIP flag, and the Web UI has no preferences store to read `ip2country.supported` from). Also fills three gaps in the peer table -- fields /clients has always returned but nothing painted: Address (`ip:port`), OS (`os_info`) and User hash. All three start hidden in every consumer, so they only widen the table once picked from the column picker. Peer columns now run CC, Address, Name, User hash, Software, OS, File, so each identity field sits next to the one it qualifies. The four transfer totals are relabelled to the compact DL/UL total and DL/UL session, which also lets all four share one width. The server table is reordered to match (CC, Address, Name, Description, Users, Files, Version, Ping, Priority, Actions) and starts with Address, Version and Ping hidden, keeping the default view to what identifies a server and how busy it is. Description also drops its fixed 180px and splits the leftover width with Name, since descriptions are long (forum URLs, blurbs). Both tables' Name columns lose their `always` flag, so the picker offers them like any other column -- with Address and CC available, the name is no longer the only way to tell rows apart. Downloads / Shared / Search keep theirs pinned: there the name column anchors the row-selection checkbox. Two pre-existing bugs this surfaced, both fixed for every list view: * A header label wider than its column spilled over the neighbouring header instead of being clipped (`white-space: nowrap`, and no overflow rule of its own) -- which is why a "Country" label looked like it fit 70px. Headers now ellipsize and carry the full label as a title tooltip, so a translation that outgrows its column stays readable on hover. * The server Address column sorted its `ip:port` strings lexically, putting 10.x before 9.x and .182 before .87. Both tables now sort it by IP value through one shared `ipNum` helper in table.js, next to the other sort/filter helpers. Peer detail-only fields (GET /clients/{ecid}) are untouched: they need a peer detail panel, not a column.
got3nks
added a commit
to got3nks/amule
that referenced
this pull request
Jul 29, 2026
Since amule-project#440 the core resolves each ed2k server's host country and hands it to the GUI, but the two lists rendered the same piece of data two different ways: the peer list drew a flag bitmap, while the server list prefixed the Server Name column with the ISO code ("de - ServerName", or "? - " when unresolved). The prefix ate horizontal space in a column that is often too narrow already and broke up the name itself. The server list now draws the same flag the peer list does, with the same rule for the unresolved case: no icon rather than a placeholder. Getting an icon into that column meant finishing a migration that was started when the virtual lists landed and deliberately left out: the server list was the last report-mode CMuleListCtrl of the pair, and only a virtual list can answer OnGetItemColumnImage per row. CServerListCtrl now derives from CMuleVirtualListCtrl and renders its cells on demand from the model via GetItemColumnText, which also buys what the other virtual lists already have -- O(1) row lookup instead of the linear FindItem that RefreshServer, RemoveServer and HighlightServer each ran, a std::sort over the model instead of moving native rows, and one coalesced re-sort per update batch instead of an inline SortList per refreshed server. Ping, Users and Files are declared live-sort columns, so sorting by one of them now follows the data. Three things had to be rebuilt against the model rather than the native items: - The connected server's bold font moves from a per-item wxListItem to OnGetItemAttr; HighlightServer just moves m_connected and repaints. - FitColumnsToContent measures the model itself. wxLIST_AUTOSIZE is a no-op on a virtual control -- it has no native items to measure and returns a default width -- so only the header half can still be left to wxLIST_AUTOSIZE_USEHEADER. - RemoveAllServers collects its victims before deleting any, instead of deleting while walking row indices. The confirmations it raises run a nested event loop, and a row index does not survive that; a server pointer does. The flags go in a small image list owned by this one control, seeded with the header sort arrows so they keep their indices, rather than in the list every CMuleListCtrl shares. Each flag is padded onto a transparent 16x16 cell -- wxImageList has one fixed size, and the bundled flags are 16x11, so adding them as-is would stretch them. The gate deciding which country code to show was duplicated between the two lists, and the server list's copy had an extra thePrefs::IsGeoIPEnabled() check that the peer list deliberately does not have. It is redundant on both paths: the core only emits its country tag when its resolver is on, so a tag received over EC already implies it, and the monolithic local lookup is guarded by the resolver's own IsEnabled(). On amulegui that pref is merely a mirror of the core's, refreshed at prefs-sync time, so consulting it could only ever disagree with the tag we were handed. Both lists now share GetDisplayCountryCode(). That helper is a header, not a .cpp, because the answer depends on ENABLE_IP2COUNTRY / CLIENT_GUI and those are per-target compile definitions. CountryFlags.cpp -- the obvious neighbour -- is built into muleappgui, one static library linked into both binaries with neither define set, where it could only ever produce the amulegui answer. Two base-class methods assumed native items and were dead against a virtual model: GetSelectedItems returned nothing, and DeleteAllItems left the model holding pointers to objects the caller was about to free. Both are now handled in CMuleVirtualListCtrl. No new translatable strings.
ngosang
pushed a commit
to ngosang/amule
that referenced
this pull request
Jul 29, 2026
…#691) Since amule-project#440 the core resolves each ed2k server's host country and hands it to the GUI, but the two lists rendered the same piece of data two different ways: the peer list drew a flag bitmap, while the server list prefixed the Server Name column with the ISO code ("de - ServerName", or "? - " when unresolved). The prefix ate horizontal space in a column that is often too narrow already and broke up the name itself. The server list now draws the same flag the peer list does, with the same rule for the unresolved case: no icon rather than a placeholder. Getting an icon into that column meant finishing a migration that was started when the virtual lists landed and deliberately left out: the server list was the last report-mode CMuleListCtrl of the pair, and only a virtual list can answer OnGetItemColumnImage per row. CServerListCtrl now derives from CMuleVirtualListCtrl and renders its cells on demand from the model via GetItemColumnText, which also buys what the other virtual lists already have -- O(1) row lookup instead of the linear FindItem that RefreshServer, RemoveServer and HighlightServer each ran, a std::sort over the model instead of moving native rows, and one coalesced re-sort per update batch instead of an inline SortList per refreshed server. Ping, Users and Files are declared live-sort columns, so sorting by one of them now follows the data. Three things had to be rebuilt against the model rather than the native items: - The connected server's bold font moves from a per-item wxListItem to OnGetItemAttr; HighlightServer just moves m_connected and repaints. - FitColumnsToContent measures the model itself. wxLIST_AUTOSIZE is a no-op on a virtual control -- it has no native items to measure and returns a default width -- so only the header half can still be left to wxLIST_AUTOSIZE_USEHEADER. - RemoveAllServers collects its victims before deleting any, instead of deleting while walking row indices. The confirmations it raises run a nested event loop, and a row index does not survive that; a server pointer does. The flags go in a small image list owned by this one control, seeded with the header sort arrows so they keep their indices, rather than in the list every CMuleListCtrl shares. Each flag is padded onto a transparent 16x16 cell -- wxImageList has one fixed size, and the bundled flags are 16x11, so adding them as-is would stretch them. The gate deciding which country code to show was duplicated between the two lists, and the server list's copy had an extra thePrefs::IsGeoIPEnabled() check that the peer list deliberately does not have. It is redundant on both paths: the core only emits its country tag when its resolver is on, so a tag received over EC already implies it, and the monolithic local lookup is guarded by the resolver's own IsEnabled(). On amulegui that pref is merely a mirror of the core's, refreshed at prefs-sync time, so consulting it could only ever disagree with the tag we were handed. Both lists now share GetDisplayCountryCode(). That helper is a header, not a .cpp, because the answer depends on ENABLE_IP2COUNTRY / CLIENT_GUI and those are per-target compile definitions. CountryFlags.cpp -- the obvious neighbour -- is built into muleappgui, one static library linked into both binaries with neither define set, where it could only ever produce the amulegui answer. Two base-class methods assumed native items and were dead against a virtual model: GetSelectedItems returned nothing, and DeleteAllItems left the model holding pointers to objects the caller was about to free. Both are now handled in CMuleVirtualListCtrl. No new translatable strings.
ngosang
added a commit
to ngosang/amule
that referenced
this pull request
Jul 30, 2026
…mule-project#687) (amule-project#719) 1bc9d6e (amule-project#694) added GET /flags/{code}.png, but nothing consumed it: the country column of the peer list and of the ed2k server list still painted only the bare uppercase code, duplicating the same one-liner cell in two views. Both now render through a single new CountryCell in components.js: the 16x11 famfamfam flag from the route followed by the code, the layout the desktop lists already use. The image URL is built relative to window.location.pathname like BASE in api.js, so it survives a reverse-proxy subpath, and the route's one-day Cache-Control means a peer list full of <img> tags doesn't re-fetch a flag per country on reload. country_code is an empty string when the daemon's GeoIP is off or the IP doesn't resolve (amule-project#439, amule-project#440), so an empty code short-circuits to the dash the cell already showed -- no <img>, and in particular no request for the "/flags/.png" the route would 404. A well-formed code the flag set has no artwork for (zz, GeoIP pseudo-codes like ap/eu) also 404s, so onError hides the image and leaves the code readable instead of a broken-image icon. The cell gains a title with the localized country name via Intl.DisplayNames ({ type: "region" }) in the UI language, as docs/api/REFERENCE.md prescribes: no endpoint and no new translation keys, since the browser already has the data. The formatter is built once per module load, not once per row. Column width goes 52px -> 70px to fit flag + code + sort arrow; sortVal is unchanged, so the column still sorts by code. Verified against a live daemon: flags render in the Networks server list and the Clients list, an empty country_code shows the dash alone, /flags/zz.png falls back to the hidden image, the tooltip follows the EN/ES switch (France/Francia), sorting works both directions, and the console stays clean.
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.
Fixes UPnP identification.