basic porting work for SCSite
Matt S Trout [Fri, 3 Aug 2012 19:07:44 +0000 (19:07 +0000)]
lib/App/SCS.pm
lib/App/SCS/LatestPageSet.pm [new file with mode: 0644]
lib/App/SCS/Page.pm
lib/App/SCS/PageSet.pm
lib/App/SCS/Plugin/Core/PagePlugin/Template.pm
lib/App/SCS/Plugin/Feeds.pm
lib/App/SCS/Plugin/Feeds/Generator.pm
lib/App/SCS/Plugin/Server.pm [new file with mode: 0644]
lib/App/SCS/Role/PageChildren.pm
lib/App/SCS/Role/Plugin.pm

index 56b393b..ca1d791 100644 (file)
@@ -62,8 +62,9 @@ sub _build_web {
 sub BUILD {
   my ($self) = @_;
   $self->load_plugin(Core => {});
-  foreach my $spec (@{$self->config->{plugins}||[]}) {
-    $self->load_plugin(@$spec);
+  my @plist = @{$self->config->{plugins}||[]};
+  while (my ($name, $conf) = splice @plist, 0, 2) {
+    $self->load_plugin($name, $conf);
   }
 }
 
@@ -79,4 +80,27 @@ sub load_plugin {
   return;
 }
 
+sub run_if_script {
+  my $self = shift;
+  if (caller(1)) {
+    return 1;
+  } else {
+    return $self->run;
+  }
+}
+
+sub run {
+  my $self = shift;
+  my $env = {
+    argv => \@ARGV,
+    stdin => \*STDIN,
+    stdout => \*STDOUT,
+    stderr => \*STDERR,
+  };
+  foreach my $p (@{$self->plugins}) {
+    return if $p->run_cli($env);
+  }
+  $self->web->run;
+}
+
 1;
diff --git a/lib/App/SCS/LatestPageSet.pm b/lib/App/SCS/LatestPageSet.pm
new file mode 100644 (file)
index 0000000..3e833ed
--- /dev/null
@@ -0,0 +1,22 @@
+package App::SCS::LatestPageSet;
+
+use Moo;
+
+has _parent => (is => 'ro', required => 1, init_arg => 'parent');
+has _max_entries => (is => 'ro', required => 1, init_arg => 'max_entries');
+
+sub flatten {
+  my ($self) = @_;
+  my @sorted = sort {
+    $b->created cmp $a->created
+  } $self->_parent->flatten;
+  my $max = $self->_max_entries||0;
+  $max && @sorted > $max ? @sorted[0..$max-1] : @sorted;
+}
+
+sub map {
+  my ($self, $mapper) = @_;
+  [ map $mapper->($_), $self->flatten ]
+}
+
+1;
index a05c5e9..0c2e76f 100644 (file)
@@ -7,6 +7,12 @@ use List::Util qw(reduce);
 use Module::Runtime qw(use_module);
 use Moo;
 
+has "_$_" => (is => 'ro', init_arg => $_) for qw(page_set);
+
+sub _page_set_class { ref($_[0]->_page_set) }
+sub _top_dir { $_[0]->_page_set->top_dir }
+sub _my_path { io->dir($_[0]->_top_dir)->catdir($_[0]->path) }
+
 with 'App::SCS::Role::PageChildren';
 
 has $_ => (is => 'ro') for qw(
@@ -65,12 +71,6 @@ sub published_at {
     : ''
 }
 
-has "_$_" => (is => 'ro', init_arg => $_) for qw(page_set);
-
-sub _page_set_class { ref($_[0]->_page_set) }
-sub _top_dir { $_[0]->_page_set->top_dir }
-sub _my_path { io->dir($_[0]->_top_dir)->catdir($_[0]->path) }
-
 sub to_app {
   my ($self) = @_;
   return sub { $self->to_psgi_response(@_) };
index 9dfc792..2b4ccf0 100644 (file)
@@ -33,6 +33,7 @@ sub _build_rel_path {
     ->catdir(File::Spec->abs2rel($self->base_dir->name, $self->top_dir->name))
 }
 
+sub _page_set { $_[0] }
 sub _page_set_class { ref($_[0]) }
 sub _top_dir { shift->top_dir }
 sub _my_path { shift->base_dir }
@@ -167,7 +168,6 @@ sub _extract_from_html {
 
 sub _extract_from_md {
   my ($self, $md) = @_;
-  #warn markdown($md, { document_format => 'complete' });
   $self->_extract_from_html(markdown($md, { document_format => 'complete' }));
 }
 
index 0587b80..e0eab28 100644 (file)
@@ -49,7 +49,11 @@ sub filter_html_zoom {
                ->then
                ->replace(sub {
                    my $sel = $to_replace[0]->{attrs}{'data-replace'};
-                   $orig->collect($sel, { into => \my @replace_with })->run;
+                   my $content = $sel =~ s/^content-of:\s*//;
+                   $orig->collect($sel, {
+                     into => \my @replace_with,
+                     content => $content
+                   })->run;
                    HTML::Zoom::ArrayStream->new({ array => \@replace_with })
                  })
                ->to_stream;
index abd8dcd..eee4c25 100644 (file)
@@ -25,6 +25,7 @@ sub page_dispatchers {
   my $base = $self->mount_at;
   "/${base}/**/" => sub {
     if (my $conf = $self->config->{$_[1]}) {
+      $conf = { base => $_[1], %$conf };
       $self->_feed_http_response(200 => $conf => $_[-1]);
     }
   },
index f2fdb21..9e9f959 100644 (file)
@@ -52,7 +52,7 @@ sub _config_to_data {
            use HTML::Tags;
            join '', HTML::Tags::to_html_string(<p>, $_->description, </p>)
          },
-         content_html => $self->_absolutify_html($_->body, $base_url, $page_url),
+         content_html => $self->_content_html($_, $base_url, $page_url),
          created => join('T', split(' ',$_->created)).'Z',
          web_url => $page_url,
        }
@@ -116,9 +116,13 @@ sub _entry_data_to_tags {
   '  ', </entry>, "\n";
 }
 
-sub _absolutify_html {
-  my ($self, $html, $base_url, $page_url) = @_;
-  $html;
+sub _content_html {
+  my ($self, $page, $base_url, $page_url) = @_;
+  my @ev;
+  HTML::Zoom->from_html($page->html)
+            ->collect(body => { into => \@ev })
+            ->run;
+  HTML::Zoom->from_events(\@ev)->to_html;
 }
 
 1;
diff --git a/lib/App/SCS/Plugin/Server.pm b/lib/App/SCS/Plugin/Server.pm
new file mode 100644 (file)
index 0000000..13cf90b
--- /dev/null
@@ -0,0 +1,41 @@
+package App::SCS::Plugin::Server;
+
+use Module::Runtime qw(use_module);
+use Moo;
+no warnings::illegalproto;
+
+with 'App::SCS::Role::Plugin';
+
+has _static_handler => (is => 'lazy');
+
+sub _build__static_handler {
+  my ($self) = @_;
+  use_module('Plack::App::File')->new(
+    root => $self->app->share_dir->catdir('static')
+  );
+}
+
+sub page_dispatchers {
+  my ($self) = @_;
+  sub (/**.*) {
+    my $path = $_[1];
+    return unless $path =~ s/\/-/\//;
+    App::SCS::Web::redispatch_to("/static/${path}");
+  },
+  sub (/static/...) { $self->_static_handler },
+  sub (/favicon + .ico) { $self->_static_handler },
+}
+
+sub run_command_server {
+  my ($self, $env) = @_;
+  my @args = @{$env->{argv}};
+  my $r = use_module('Plack::Runner')->new(
+    server => 'Starman',
+    app => $self->app->web->to_psgi_app
+  );
+  $r->parse_options(@args);
+  $r->set_options(argv => \@args);
+  $r->run;
+}
+
+1;
index 3e6f2f3..eb5e897 100644 (file)
@@ -2,6 +2,7 @@ package App::SCS::Role::PageChildren;
 
 use Moo::Role;
 
+requires '_page_set';
 requires '_page_set_class';
 requires '_top_dir';
 requires '_my_path';
@@ -15,6 +16,7 @@ sub children {
     top_dir => $self->_top_dir,
     base_dir => $self->_my_path,
     max_depth => 1,
+    plugin_config => $self->_page_set->plugin_config,
     %args,
   );
 }
index c134fc3..c842e12 100644 (file)
@@ -19,4 +19,13 @@ sub provides_pages { () }
 
 sub register { return }
 
+sub run_cli {
+  my ($self, $env) = @_;
+  my ($command, @argv) = @{$env->{argv}};
+  return unless $command;
+  return unless $self->can(my $meth = "run_command_${command}");
+  $self->$meth({ argv => \@argv, %$env });
+  return 1;
+}
+
 1;