tarballs.pl 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #!/usr/bin/env perl
  2. use Modern::Perl;
  3. use Mojolicious::Lite;
  4. use Mojo::Cache;
  5. use Archive::Tar;
  6. use File::Basename;
  7. use Sort::Versions;
  8. use Encode qw(decode_utf8);
  9. my $dir = "/home/alex/oddmuse.org/releases";
  10. my $cache = Mojo::Cache->new(max_keys => 50);
  11. sub tarballs {
  12. my @tarballs = reverse sort versioncmp map {
  13. my ($name, $path, $suffix) = fileparse($_, '.tar.gz');
  14. $name;
  15. } <$dir/*.tar.gz>;
  16. return \@tarballs;
  17. }
  18. sub tarball {
  19. my $tarball = shift;
  20. if ($tarball eq 'latest') {
  21. my $tarballs = tarballs();
  22. $tarball = shift @$tarballs;
  23. }
  24. return $tarball;
  25. }
  26. get '/' => sub {
  27. my $c = shift;
  28. my $tarballs = tarballs();
  29. unshift @$tarballs, 'latest';
  30. $c->render(template => 'index', tarballs => $tarballs);
  31. } => 'main';
  32. get '/#tarball' => sub {
  33. my $c = shift;
  34. my $tarball = tarball $c->param('tarball');
  35. my $files = $cache->get($tarball);
  36. if (not $files) {
  37. $c->app->log->info("Reading $tarball.tar.gz");
  38. my $tar = Archive::Tar->new;
  39. $tar->read("$dir/$tarball.tar.gz");
  40. my @files = sort grep /./, map {
  41. my @e = split('/', $_->name);
  42. $e[1];
  43. } $tar->get_files();
  44. $files = \@files;
  45. $cache->set($tarball => $files);
  46. }
  47. $c->render(template => 'release', tarball=> $tarball, files => $files);
  48. } => 'release';
  49. get '/#tarball/#file' => sub {
  50. my $c = shift;
  51. my $tarball = tarball $c->param('tarball');
  52. my $file = $c->param('file');
  53. my $text = $cache->get("$tarball/$file");
  54. if (not $text) {
  55. $c->app->log->info("Reading $tarball/$file");
  56. my $tar = Archive::Tar->new;
  57. $tar->read("$dir/$tarball.tar.gz");
  58. $text = decode_utf8($tar->get_content("$tarball/$file"));
  59. $cache->set("$tarball/$file" => $text);
  60. }
  61. if ($text) {
  62. $c->render(template => 'file', format => 'txt', content => $text);
  63. } else {
  64. $c->render(template => 'missing');
  65. }
  66. } => 'file';
  67. app->start;
  68. __DATA__
  69. @@ index.html.ep
  70. % layout 'default';
  71. % title 'Oddmuse Releases';
  72. <h1>Oddmuse Releases</h1>
  73. <p>Welcome! This is where you get access to tarballs and files in released
  74. versions of Oddmuse.</p>
  75. <ul>
  76. % for my $tarball (@$tarballs) {
  77. <li>
  78. % if ($tarball ne 'latest') {
  79. <a href="https://oddmuse.org/releases/<%= $tarball %>.tar.gz"><%= $tarball %>.tar.gz</a>
  80. % }
  81. (files for <%= link_to release => {tarball => $tarball} => begin %>\
  82. <%= $tarball =%><%= end %>)
  83. </li>
  84. % }
  85. </ul>
  86. @@ release.html.ep
  87. % layout 'default';
  88. % title 'Release';
  89. <h1>Files for <%= $tarball %></h1>
  90. <p>
  91. Back to the list of <%= link_to 'releases' => 'main' %>.
  92. Remember,
  93. %= link_to file => {file => 'wiki.pl'} => begin
  94. wiki.pl
  95. % end
  96. is the main script.
  97. <ul>
  98. % for my $file (@$files) {
  99. <li>
  100. %= link_to file => {file => $file} => begin
  101. %= $file
  102. % end
  103. % }
  104. </ul>
  105. @@ file.txt.ep
  106. %layout 'file';
  107. <%== $content %>
  108. @@ missing.html.ep
  109. % layout 'default';
  110. % title 'Missing File';
  111. <h1><%= $tarball %> is missing <%= $file %></h1>
  112. <p>
  113. You can go back to the list of <%= link_to 'releases' => 'main' %>,
  114. or you can try to find <%= $file %> in the
  115. <a href="https://raw.githubusercontent.com/kensanata/oddmuse/master/modules/<%= $file %>">unstable modules</a> section on GitHub.
  116. @@ layouts/default.html.ep
  117. <!DOCTYPE html>
  118. <html>
  119. <head>
  120. <title><%= title %></title>
  121. %= stylesheet '/tarballs.css'
  122. %= stylesheet begin
  123. body {
  124. padding: 1em;
  125. font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif;
  126. }
  127. % end
  128. <meta name="viewport" content="width=device-width">
  129. </head>
  130. <body>
  131. <%= content %>
  132. <hr>
  133. <p>
  134. <a href="https://oddmuse.org/">Oddmuse</a>&#x2003;
  135. <%= link_to 'Releases' => 'main' %>&#x2003;
  136. <a href="https://alexschroeder.ch/wiki/Contact">Alex Schroeder</a>
  137. </body>
  138. </html>