JSON.pm 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package Trog::Routes::JSON;
  2. use strict;
  3. use warnings;
  4. no warnings 'experimental';
  5. use feature qw{signatures};
  6. use Digest::SHA();
  7. use JSON::MaybeXS();
  8. use Trog::Config();
  9. my $conf = Trog::Config::get();
  10. # TODO de-duplicate this, it's shared in html
  11. my $theme_dir = '';
  12. $theme_dir = "themes/".$conf->param('general.theme') if $conf->param('general.theme') && -d "www/themes/".$conf->param('general.theme');
  13. our %routes = (
  14. '/api/catalog' => {
  15. method => 'GET',
  16. callback => \&catalog,
  17. parameters => [],
  18. },
  19. '/api/webmanifest' => {
  20. method => 'GET',
  21. callback => \&webmanifest,
  22. parameters => [],
  23. },
  24. );
  25. my $headers = ['Content-type' => "application/json"];
  26. sub catalog ($query) {
  27. my $enc = JSON::MaybeXS->new( utf8 => 1 );
  28. my %rcopy = %{\%routes};
  29. foreach my $r (keys(%rcopy)) {
  30. delete $rcopy{$r}{callback}
  31. }
  32. # Make the ETag the sha256 of the routes
  33. my $content = $enc->encode(\%rcopy);
  34. my $state = Digest::SHA->new(256);
  35. my $hash = $state->add($content);
  36. push(@$headers, ETag => $state->hexdigest);
  37. return [200,$headers,[$content]];
  38. }
  39. sub webmanifest ($query) {
  40. my $enc = JSON::MaybeXS->new( utf8 => 1 );
  41. my %manifest = (
  42. "icons" => [
  43. { "src" => "$theme_dir/img/icon/favicon-192.png", "type" => "image/png", "sizes" => "192x192" },
  44. { "src" => "$theme_dir/img/icon/favicon-512.png", "type" => "image/png", "sizes" => "512x512" },
  45. ],
  46. );
  47. # Make the ETag the sha256 of the routes
  48. my $content = $enc->encode(\%manifest);
  49. my $state = Digest::SHA->new(256);
  50. my $hash = $state->add($content);
  51. push(@$headers, ETag => $state->hexdigest);
  52. return [ 200, $headers, [$content] ];
  53. }
  54. 1;