basic show works
Matt S Trout [Wed, 12 Jan 2011 12:09:18 +0000 (12:09 +0000)]
lib/App/Commentry.pm [new file with mode: 0644]
lib/App/Commentry/CommentSet.pm
lib/App/Commentry/MappedSet.pm [new file with mode: 0644]

diff --git a/lib/App/Commentry.pm b/lib/App/Commentry.pm
new file mode 100644 (file)
index 0000000..f60074c
--- /dev/null
@@ -0,0 +1,73 @@
+package App::Commentry;
+
+use aliased 'App::Commentry::CommentStore';
+use FindBin;
+use HTML::Zoom;
+use Web::Simple;
+
+sub default_config {
+  (
+    store_dir => $FindBin::Bin.'/../store/comments',
+    template_dir => $FindBin::Bin.'/../share/html',
+  )
+}
+
+has comment_store => (
+  is => 'lazy', handles => { 'comments_for' => 'get' }
+);
+
+sub _build_comment_store {
+  my $self = shift;
+  my $store_dir = $self->config->{store_dir};
+  die "Comment Store directory ${store_dir} does not exist"
+    unless -d $store_dir;
+  CommentStore->new(base_dir => $self->config->{store_dir});
+}
+
+has template_dir => (
+  is => 'lazy'
+);
+
+sub _build_template_dir {
+  my $self = shift;
+  my $template_dir = $self->config->{template_dir};
+  die "template_dir ${template_dir} does not exist"
+    unless -d $template_dir;
+  $template_dir;
+}
+
+sub dispatch_request {
+  my ($self) = @_;
+  sub (/fragments/*/**) {
+    my ($self, $action, $path) = @_;
+    return unless $action eq 'show' or $action eq 'add';
+    return unless my $set = $self->comments_for({ path => $path });
+    $self->${\"_fragment_${action}"}($set);
+  }
+}
+
+sub _fragment_show {
+  my ($self, $set) = @_;
+  sub (GET) {
+    $self->_zoom_response(fragment_show => sub {
+      $_->select('.comment')
+        ->repeat($set->map(sub {
+            my ($comment) = @_;
+            sub {
+              $_->select('.comment-title')->replace_content($comment->title)
+                ->select('.comment-body')->replace_content($comment->body)
+            }
+          }));
+    });
+  }
+}
+
+sub _zoom_response {
+  my ($self, $template, $apply) = @_;
+  my $zfh = ($self->{zoom_cache}{$template} ||= do {
+    HTML::Zoom->from_file($self->template_dir.'/'.$template.'.html')
+  })->apply($apply)->to_fh;
+  [ 200, [ 'Content-type' => 'text/html' ], $zfh ];
+}
+
+1;
index 2419cf2..ba41cfc 100644 (file)
@@ -30,4 +30,10 @@ sub flatten {
   @{$self->_members};
 }
 
+sub map {
+  my ($self, $mapping) = @_;
+  require App::Commentry::MappedSet;
+  App::Commentry::MappedSet->new(source => $self, mapping => $mapping);
+}
+
 1;
diff --git a/lib/App/Commentry/MappedSet.pm b/lib/App/Commentry/MappedSet.pm
new file mode 100644 (file)
index 0000000..30bae3e
--- /dev/null
@@ -0,0 +1,18 @@
+package App::Commentry::MappedSet;
+
+use Moo;
+
+has source => (is => 'ro', required => 1);
+has mapping => (is => 'ro', required => 1);
+
+sub flatten {
+  my ($self) = @_;
+  map $self->mapping->($_), $self->source->flatten;
+}
+
+sub to_stream {
+  require HTML::Zoom::ArrayStream;
+  HTML::Zoom::ArrayStream->new({ array => [ $_[0]->flatten ] });
+}
+
+1;