From 4b313dc74bc9bb84a542b7ec920cdb92879e7523 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 20 Jun 2016 00:57:16 +0000 Subject: feed: various object-orientation cleanups Favor Inbox objects as our primary source of truth to simplify our code. This increases our coupling with PSGI to make it easier to write tests in the future. A lot of this code was originally designed to be usable standalone without PSGI or CGI at all; but that might increase development effort. --- lib/PublicInbox/Feed.pm | 58 +++++++++++++++----------------------------- lib/PublicInbox/Inbox.pm | 12 +++++++++ lib/PublicInbox/Mbox.pm | 10 +++----- lib/PublicInbox/NNTP.pm | 6 ++--- lib/PublicInbox/View.pm | 7 +++--- lib/PublicInbox/WWW.pm | 4 +-- lib/PublicInbox/WwwAttach.pm | 5 +--- 7 files changed, 43 insertions(+), 59 deletions(-) (limited to 'lib/PublicInbox') diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm index 07dce9ee..455b8e23 100644 --- a/lib/PublicInbox/Feed.pm +++ b/lib/PublicInbox/Feed.pm @@ -65,14 +65,14 @@ sub emit_atom { my $fh = $cb->([ 200, ['Content-Type' => 'application/atom+xml']]); my $max = $ctx->{max} || MAX_PER_PAGE; my $x = atom_header($feed_opts); - my $git = $ctx->{git} ||= PublicInbox::Git->new($ctx->{git_dir}); + my $ibx = $ctx->{-inbox}; each_recent_blob($ctx, sub { my ($path, undef, $ts) = @_; if (defined $x) { $fh->write($x . feed_updated(undef, $ts)); $x = undef; } - my $s = feed_entry($feed_opts, $path, $git) or return 0; + my $s = feed_entry($feed_opts, $path, $ibx) or return 0; $fh->write($s); 1; }); @@ -103,9 +103,9 @@ sub emit_atom_thread { $feed_opts->{url} = $html_url; $feed_opts->{emit_header} = 1; - my $git = $ctx->{git} ||= PublicInbox::Git->new($ctx->{git_dir}); + my $ibx = $ctx->{-inbox}; foreach my $msg (@{$res->{msgs}}) { - my $s = feed_entry($feed_opts, mid2path($msg->mid), $git); + my $s = feed_entry($feed_opts, mid2path($msg->mid), $ibx); $fh->write($s) if defined $s; } end_feed($fh); @@ -167,12 +167,12 @@ sub emit_html_index { sub emit_index_nosrch { my ($ctx, $state) = @_; - my $git = $ctx->{git} ||= PublicInbox::Git->new($ctx->{git_dir}); + my $ibx = $ctx->{-inbox}; my (undef, $last) = each_recent_blob($ctx, sub { my ($path, $commit, $ts, $u, $subj) = @_; $state->{first} ||= $commit; - my $mime = do_cat_mail($git, $path) or return 0; + my $mime = do_cat_mail($ibx, $path) or return 0; PublicInbox::View::index_entry($mime, 0, $state); 1; }); @@ -218,8 +218,8 @@ sub each_recent_blob { # get recent messages # we could use git log -z, but, we already know ssoma will not # leave us with filenames with spaces in them.. - my $git = $ctx->{git} ||= PublicInbox::Git->new($ctx->{git_dir}); - my $log = $git->popen(qw/log --no-notes --no-color --raw -r + my $log = $ctx->{-inbox}->git->popen(qw/log + --no-notes --no-color --raw -r --abbrev=16 --abbrev-commit/, "--format=%h%x00%ct%x00%an%x00%s%x00", $range); @@ -269,31 +269,16 @@ sub get_feedopts { my $inbox = $ctx->{inbox}; my $obj = $ctx->{-inbox}; my $cgi = $ctx->{cgi}; - my %rv = ( description => $obj ? $obj->description : 'FIXME' ); - - if ($obj) { - $rv{address} = $obj->{address}; - $rv{id_addr} = $obj->{-primary_address}; - } elsif ($pi_config && defined $inbox && $inbox ne '') { - # TODO: remove - my $addr = $pi_config->get($inbox, 'address') || ""; - $rv{address} = $addr; - $addr = $addr->[0] if ref($addr); - $rv{id_addr} = $addr; - } - $rv{id_addr} ||= 'public-inbox@example.com'; + my %rv = ( description => $obj->description ); + $rv{address} = $obj->{address}; + $rv{id_addr} = $obj->{-primary_address}; my $url_base; - if ($obj) { - $url_base = $obj->base_url($cgi); # CGI may be undef - if (my $mid = $ctx->{mid}) { # per-thread feed: - $rv{atomurl} = "$url_base$mid/t.atom"; - } else { - $rv{atomurl} = $url_base."new.atom"; - } + $url_base = $obj->base_url($cgi); # CGI may be undef + if (my $mid = $ctx->{mid}) { # per-thread feed: + $rv{atomurl} = "$url_base$mid/t.atom"; } else { - $url_base = 'http://example.com/'; - $rv{atomurl} = $url_base.'new.atom'; + $rv{atomurl} = $url_base."new.atom"; } $rv{url} ||= $url_base; $rv{midurl} = $url_base; @@ -311,9 +296,9 @@ sub feed_updated { # returns undef or string sub feed_entry { - my ($feed_opts, $add, $git) = @_; + my ($feed_opts, $add, $ibx) = @_; - my $mime = do_cat_mail($git, $add) or return; + my $mime = do_cat_mail($ibx, $add) or return; my $url = $feed_opts->{url}; my $midurl = $feed_opts->{midurl}; @@ -357,12 +342,9 @@ sub feed_entry { } sub do_cat_mail { - my ($git, $path) = @_; - my $mime = eval { - my $str = $git->cat_file("HEAD:$path"); - Email::MIME->new($str); - }; - $@ ? undef : $mime; + my ($ibx, $path) = @_; + my $mime = eval { $ibx->msg_by_path($path) } or return; + Email::MIME->new($mime); } 1; diff --git a/lib/PublicInbox/Inbox.pm b/lib/PublicInbox/Inbox.pm index c982d0b4..faab03ce 100644 --- a/lib/PublicInbox/Inbox.pm +++ b/lib/PublicInbox/Inbox.pm @@ -7,6 +7,7 @@ use strict; use warnings; use Scalar::Util qw(weaken); use PublicInbox::Git; +use PublicInbox::MID qw(mid2path); sub new { my ($class, $opts) = @_; @@ -90,4 +91,15 @@ sub nntp_usable { $ret; } +sub msg_by_path ($$;$) { + my ($self, $path, $ref) = @_; + # TODO: allow other refs: + git($self)->cat_file('HEAD:'.$path, $ref); +} + +sub msg_by_mid ($$;$) { + my ($self, $mid, $ref) = @_; + msg_by_path($self, mid2path($mid), $ref); +} + 1; diff --git a/lib/PublicInbox/Mbox.pm b/lib/PublicInbox/Mbox.pm index 0258d8c7..63ec605f 100644 --- a/lib/PublicInbox/Mbox.pm +++ b/lib/PublicInbox/Mbox.pm @@ -107,7 +107,6 @@ EOF package PublicInbox::MboxGz; use strict; use warnings; -use PublicInbox::MID qw(mid2path); sub new { my ($class, $ctx, $cb) = @_; @@ -135,15 +134,12 @@ sub getline { my ($self) = @_; my $res; my $ctx = $self->{ctx}; - my $git = $ctx->{git}; + my $ibx = $ctx->{-inbox}; my $gz = $self->{gz}; do { while (defined(my $smsg = shift @{$self->{msgs}})) { - my $msg = eval { - my $p = 'HEAD:'.mid2path($smsg->mid); - Email::Simple->new($git->cat_file($p)); - }; - $msg or next; + my $msg = eval { $ibx->msg_by_mid($smsg->mid) } or next; + $msg = Email::Simple->new($msg); $gz->write(PublicInbox::Mbox::msg_str($ctx, $msg)); my $ret = _flush_buf($self); return $ret if $ret; diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm index e8683210..93f654f6 100644 --- a/lib/PublicInbox/NNTP.pm +++ b/lib/PublicInbox/NNTP.pm @@ -10,7 +10,6 @@ use fields qw(nntpd article rbuf ng long_res); use PublicInbox::Search; use PublicInbox::Msgmap; use PublicInbox::Git; -use PublicInbox::MID qw(mid2path); require PublicInbox::EvCleanup; use Email::Simple; use POSIX qw(strftime); @@ -481,10 +480,9 @@ find_mid: defined $mid or return $err; } found: - my $o = 'HEAD:' . mid2path($mid); my $bytes; - my $s = eval { Email::Simple->new($ng->git->cat_file($o, \$bytes)) }; - return $err unless $s; + my $s = eval { $ng->msg_by_mid($mid, \$bytes) } or return $err; + $s = Email::Simple->new($s); my $lines; if ($set_headers) { set_nntp_headers($s->header_obj, $ng, $n, $mid); diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index e8ec0ed2..006da8d0 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -12,7 +12,7 @@ use Encode::MIME::Header; use Plack::Util; use PublicInbox::Hval qw/ascii_html/; use PublicInbox::Linkify; -use PublicInbox::MID qw/mid_clean id_compress mid2path mid_mime/; +use PublicInbox::MID qw/mid_clean id_compress mid_mime/; use PublicInbox::MsgIter; use PublicInbox::Address; use PublicInbox::WwwStream; @@ -581,9 +581,10 @@ sub __thread_entry { # lazy load the full message from mini_mime: $mime = eval { - my $path = mid2path(mid_clean(mid_mime($mime))); - Email::MIME->new($state->{ctx}->{git}->cat_file('HEAD:'.$path)); + my $mid = mid_clean(mid_mime($mime)); + $state->{ctx}->{-inbox}->msg_by_mid($mid); } or return; + $mime = Email::MIME->new($mime); thread_html_head($mime, $state) if $state->{anchor_idx} == 0; if (my $ghost = delete $state->{ghost}) { diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm index f88894a0..f1f4abd5 100644 --- a/lib/PublicInbox/WWW.pm +++ b/lib/PublicInbox/WWW.pm @@ -206,9 +206,7 @@ sub get_index { # just returns a string ref for the blob in the current ctx sub mid2blob { my ($ctx) = @_; - require PublicInbox::MID; - my $path = PublicInbox::MID::mid2path($ctx->{mid}); - $ctx->{git}->cat_file("HEAD:$path"); + $ctx->{-inbox}->msg_by_mid($ctx->{mid}); } # /$INBOX/$MESSAGE_ID/raw -> raw mbox diff --git a/lib/PublicInbox/WwwAttach.pm b/lib/PublicInbox/WwwAttach.pm index 5cf56a80..33bfce27 100644 --- a/lib/PublicInbox/WwwAttach.pm +++ b/lib/PublicInbox/WwwAttach.pm @@ -8,16 +8,13 @@ use warnings; use Email::MIME; use Email::MIME::ContentType qw(parse_content_type); $Email::MIME::ContentType::STRICT_PARAMS = 0; -use PublicInbox::MID qw(mid2path); use PublicInbox::MsgIter; # /$LISTNAME/$MESSAGE_ID/$IDX-$FILENAME sub get_attach ($$$) { my ($ctx, $idx, $fn) = @_; - my $path = mid2path($ctx->{mid}); - my $res = [ 404, [ 'Content-Type', 'text/plain' ], [ "Not found\n" ] ]; - my $mime = $ctx->{git}->cat_file("HEAD:$path") or return $res; + my $mime = $ctx->{-inbox}->msg_by_mid($ctx->{mid}) or return $res; $mime = Email::MIME->new($mime); msg_iter($mime, sub { my ($part, $depth, @idx) = @{$_[0]}; -- cgit v1.2.3-24-ge0c7