From 71040e5ff8a68eb0cfaf20c273e227cdceb9dc23 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 24 Aug 2015 02:25:46 +0000 Subject: view: refactor $state as a hash Using hash means we no longer have to document and remember what every field does. The original array form was insane premature optimization and crazy. Who wrote that? Oh wait, I was on drugs :< --- lib/PublicInbox/Feed.pm | 12 ++++++++---- lib/PublicInbox/View.pm | 37 ++++++++++++++++++++----------------- lib/PublicInbox/WWW.pm | 8 ++++---- t/view.t | 10 +++++----- 4 files changed, 37 insertions(+), 30 deletions(-) diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm index f4d19e02..969fc110 100644 --- a/lib/PublicInbox/Feed.pm +++ b/lib/PublicInbox/Feed.pm @@ -89,7 +89,12 @@ sub emit_html_index { $srch and $topics = [ [], {} ]; my (undef, $last) = each_recent_blob($ctx, sub { my ($path, $commit, $ts, $u, $subj) = @_; - $state ||= [ undef, {}, $commit, 0 ]; + $state ||= { + ctx => $ctx, + seen => {}, + first_commit => $commit, + anchor_idx => 0, + }; if ($srch) { add_topic($git, $srch, $topics, $path, $ts, $u, $subj); @@ -119,9 +124,8 @@ sub nav_footer { my $old_r = $cgi->param('r'); my $head = ' '; my $next = ' '; - # $state = [ undef, {}, $first_commit, $last_anchor ]; - my $first = $state->[2]; - my $anchor = $state->[3]; + my $first = $state->{first_commit}; + my $anchor = $state->{anchor_idx}; if ($last) { $next = qq!next!; diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index cf582688..64a2086d 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -25,16 +25,17 @@ my $enc_utf8 = find_encoding('UTF-8'); # public functions: sub msg_html { - my ($class, $mime, $full_pfx, $footer, $srch) = @_; + my ($ctx, $mime, $full_pfx, $footer) = @_; if (defined $footer) { $footer = "\n" . $footer; } else { $footer = ''; } + my $srch = $ctx->{srch} if $ctx; headers_to_html_header($mime, $full_pfx, $srch) . multipart_text_as_html($mime, $full_pfx) . '
' .
-		html_footer($mime, 1, $full_pfx, $srch) .
+		html_footer($mime, 1, $full_pfx, $ctx) .
 		$footer .
 		'
'; } @@ -46,11 +47,11 @@ sub feed_entry { } # this is already inside a
-# state = [ time, seen = {}, first_commit, page_nr = 0 ]
 sub index_entry {
 	my ($fh, $mime, $level, $state) = @_;
-	my ($srch, $seen, $first_commit) = @$state;
-	my $midx = $state->[3]++;
+	my $midx = $state->{anchor_idx}++;
+	my $ctx = $state->{ctx};
+	my $srch = $ctx->{srch};
 	my ($prev, $next) = ($midx - 1, $midx + 1);
 	my $part_nr = 0;
 	my $enc = enc_for($mime->header("Content-Type"));
@@ -59,6 +60,7 @@ sub index_entry {
 
 	my $mid_raw = $header_obj->header('Message-ID');
 	my $id = anchor_for($mid_raw);
+	my $seen = $state->{seen};
 	$seen->{$id} = "#$id"; # save the anchor for later
 
 	my $mid = PublicInbox::Hval->new_msgid($mid_raw);
@@ -68,8 +70,8 @@ sub index_entry {
 
 	$from = PublicInbox::Hval->new_oneline($from)->as_html;
 	$subj = PublicInbox::Hval->new_oneline($subj)->as_html;
-	my $root_anchor = $seen->{root_anchor};
 	my $more = 'permalink';
+	my $root_anchor = $state->{root_anchor};
 	my $path = $root_anchor ? '../' : '';
 	my $href = $mid->as_href;
 	my $irt = $header_obj->header('In-Reply-To');
@@ -81,7 +83,7 @@ sub index_entry {
 	} else {
 		$t_anchor = '';
 	}
-	if (defined $srch) {
+	if ($srch) {
 		$subj = "$subj";
 	}
 	if ($root_anchor && $root_anchor eq $id) {
@@ -121,7 +123,7 @@ sub index_entry {
 
 	my $txt = "${path}m/$href.txt";
 	$rv = "\n$more raw ";
-	$rv .= html_footer($mime, 0);
+	$rv .= html_footer($mime, 0, undef, $ctx);
 
 	if (defined $irt) {
 		unless (defined $anchor) {
@@ -157,13 +159,18 @@ sub emit_thread_html {
 	return missing_thread($cb) if $nr == 0;
 	my $fh = $cb->([200,['Content-Type'=>'text/html; charset=UTF-8']]);
 	my $th = thread_results($msgs);
-	my $state = [ $srch, { root_anchor => anchor_for($mid) }, undef, 0 ];
+	my $state = {
+		ctx => $ctx,
+		seen => {},
+		root_anchor => anchor_for($mid),
+		anchor_idx => 0,
+	};
 	{
 		require PublicInbox::GitCatFile;
 		my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
 		thread_entry($fh, $git, $state, $_, 0) for $th->rootset;
 	}
-	my $final_anchor = $state->[3];
+	my $final_anchor = $state->{anchor_idx};
 	my $next = "";
 	$next .= $final_anchor == 1 ? 'only message in' : 'end of';
 	$next .= " thread, back to index\n";
@@ -401,7 +408,7 @@ sub headers_to_html_header {
 }
 
 sub html_footer {
-	my ($mime, $standalone, $full_pfx, $srch) = @_;
+	my ($mime, $standalone, $full_pfx, $ctx) = @_;
 	my %cc; # everyone else
 	my $to; # this is the From address
 
@@ -429,6 +436,7 @@ sub html_footer {
 	my $cc = uri_escape_utf8(join(',', sort values %cc));
 	my $href = "mailto:$to?In-Reply-To=$irt&Cc=${cc}&Subject=$subj";
 
+	my $srch = $ctx->{srch} if $ctx;
 	my $idx = $standalone ? " index" : '';
 	if ($idx && $srch) {
 		$irt = $mime->header('In-Reply-To') || '';
@@ -541,18 +549,13 @@ sub thread_html_head {
 sub thread_entry {
 	my ($fh, $git, $state, $node, $level) = @_;
 	return unless $node;
-	# $state = [ $search_res, $seen, undef, 0 (msg_nr) ];
-	# $seen is overloaded with 3 types of fields:
-	#	1) "root_anchor" => anchor_for(Message-ID),
-	#	2) seen subject hashes: sha1(subject) => 1
-	#	3) anchors hashes: "#$sha1_hex" (same as $seen in index_entry)
 	if (my $mime = $node->message) {
 
 		# lazy load the full message from mini_mime:
 		my $path = mid2path(mid_clean($mime->header('Message-ID')));
 		$mime = eval { Email::MIME->new($git->cat_file("HEAD:$path")) };
 		if ($mime) {
-			if ($state->[3] == 0) {
+			if ($state->{anchor_idx} == 0) {
 				$fh->write(thread_html_head($mime));
 			}
 			index_entry($fh, $mime, $level, $state);
diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm
index 86c64fb6..eeae3d32 100644
--- a/lib/PublicInbox/WWW.pm
+++ b/lib/PublicInbox/WWW.pm
@@ -176,9 +176,9 @@ sub get_mid_html {
 	my $foot = footer($ctx);
 	require Email::MIME;
 	my $mime = Email::MIME->new($x);
-	my $srch = searcher($ctx);
+	searcher($ctx);
 	[ 200, [ 'Content-Type' => 'text/html; charset=UTF-8' ],
-	  [ PublicInbox::View->msg_html($mime, $pfx, $foot, $srch) ] ];
+	  [ PublicInbox::View::msg_html($ctx, $mime, $pfx, $foot) ] ];
 }
 
 # /$LISTNAME/f/$MESSAGE_ID.html                   -> HTML content (fullquotes)
@@ -190,9 +190,9 @@ sub get_full_html {
 	my $foot = footer($ctx);
 	require Email::MIME;
 	my $mime = Email::MIME->new($x);
-	my $srch = searcher($ctx);
+	searcher($ctx);
 	[ 200, [ 'Content-Type' => 'text/html; charset=UTF-8' ],
-	  [ PublicInbox::View->msg_html($mime, undef, $foot, $srch)] ];
+	  [ PublicInbox::View::msg_html($ctx, $mime, undef, $foot)] ];
 }
 
 # /$LISTNAME/t/$MESSAGE_ID.html
diff --git a/t/view.t b/t/view.t
index ca456aab..fd3c75be 100644
--- a/t/view.t
+++ b/t/view.t
@@ -41,7 +41,7 @@ EOF
 		body => $body,
 	)->as_string;
 	my $mime = Email::MIME->new($s);
-	my $html = PublicInbox::View->msg_html($mime);
+	my $html = PublicInbox::View::msg_html(undef, $mime);
 
 	# ghetto tests
 	like($html, qr!new($s);
-	my $short = PublicInbox::View->msg_html($mime, $pfx);
+	my $short = PublicInbox::View::msg_html(undef, $mime, $pfx);
 	like($short, qr! $parts,
 	);
 
-	my $html = PublicInbox::View->msg_html($mime);
+	my $html = PublicInbox::View::msg_html(undef, $mime);
 	like($html, qr/hi\n-+ part #2 -+\nbye\n/, "multipart split");
 }
 
@@ -113,7 +113,7 @@ EOF
 		parts => $parts,
 	);
 
-	my $html = PublicInbox::View->msg_html($mime);
+	my $html = PublicInbox::View::msg_html(undef, $mime);
 	like($html, qr!see attached patch\n-+ foo\.patch -+\n--- a/file\n!,
 		"parts split with filename");
 }
@@ -139,7 +139,7 @@ EOF
 	);
 
 	my $orig = $mime->body_raw;
-	my $html = PublicInbox::View->msg_html($mime);
+	my $html = PublicInbox::View::msg_html(undef, $mime);
 	like($orig, qr/hi =3D bye=/, "our test used QP correctly");
 	like($html, qr/\bhi = bye\b/, "HTML output decoded QP");
 }
-- 
cgit v1.2.3-24-ge0c7