SearchPackagesAction.vala 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. using Invercargill;
  2. using Statum;
  3. namespace UsmWeb {
  4. /**
  5. * Server-side search: filters the {@link PackagesState.SLOT_TYPE} PAGE
  6. * slot's package table by the `query` form field (case-insensitive
  7. * substring over name and summary).
  8. *
  9. * Collection-typed slot fields cannot be read back from held state, so
  10. * the filtered rows are rebuilt from the repository (the documented
  11. * rebuild-from-source pattern) and written as one slot update keyed by
  12. * the held slot's key.
  13. */
  14. public class SearchPackagesAction : StatumAction {
  15. protected RepositoryService repositories = Inversion.inject<RepositoryService>();
  16. protected UsmWebConfig config = Inversion.inject<UsmWebConfig>();
  17. protected Astralis.HttpContext http_context = Inversion.inject<Astralis.HttpContext>();
  18. public override async DirectiveBuilder handle() throws GLib.Error {
  19. string query = "";
  20. if (request.form != null) {
  21. query = (request.form.get_field("query") ?? "").strip();
  22. }
  23. HeldSlot held;
  24. if (!request.held.try_get(PackagesState.SLOT_TYPE, out held) || held == null) {
  25. return directives().error("No \"packages\" slot held — reload the page");
  26. }
  27. var base_uri = DerivedBase.derive(http_context.request, config);
  28. State state;
  29. try {
  30. state = PackagesState.build(repositories, config, action_registry, base_uri, query);
  31. } catch (Error e) {
  32. return directives().notify("error", @"Repository load failed: $(e.message)");
  33. }
  34. return directives().update(((!)held).key, state);
  35. }
  36. }
  37. }