1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 16:22:43 +01:00

Add cached summarization to PhamePost

Summary: Restore summarization. Use the remarkup cache, and try to do it somewhat-intelligently (pick the first paragraph that looks like it's text).

Test Plan:
{F21323}

{F21324}

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T1373

Differential Revision: https://secure.phabricator.com/D3715
This commit is contained in:
epriestley 2012-10-17 08:36:33 -07:00
parent 83bbad8ba0
commit 44c6109bf2
7 changed files with 99 additions and 105 deletions

View file

@ -1152,7 +1152,6 @@ phutil_register_library_map(array(
'PhameBasicBlogSkin' => 'applications/phame/skins/PhameBasicBlogSkin.php',
'PhameBlog' => 'applications/phame/storage/PhameBlog.php',
'PhameBlogDeleteController' => 'applications/phame/controller/blog/PhameBlogDeleteController.php',
'PhameBlogDetailView' => 'applications/phame/view/PhameBlogDetailView.php',
'PhameBlogEditController' => 'applications/phame/controller/blog/PhameBlogEditController.php',
'PhameBlogListController' => 'applications/phame/controller/blog/PhameBlogListController.php',
'PhameBlogLiveController' => 'applications/phame/controller/blog/PhameBlogLiveController.php',
@ -2286,7 +2285,6 @@ phutil_register_library_map(array(
2 => 'PhabricatorMarkupInterface',
),
'PhameBlogDeleteController' => 'PhameController',
'PhameBlogDetailView' => 'AphrontView',
'PhameBlogEditController' => 'PhameController',
'PhameBlogListController' => 'PhameController',
'PhameBlogLiveController' => 'PhameController',

View file

@ -39,6 +39,8 @@ extends PhameController {
PhamePost::MARKUP_FIELD_BODY,
$user);
$content = '<div class="phabricator-remarkup">'.$content.'</div>';
return id(new AphrontAjaxResponse())->setContent($content);
}
}

View file

@ -69,12 +69,17 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
}
protected function renderPostList(array $posts) {
$summaries = array();
foreach ($posts as $post) {
$summaries[] = $post->renderWithSummary();
}
$list = phutil_render_tag(
'div',
array(
'class' => 'phame-post-list',
),
id(new AphrontNullView())->appendChild($posts)->render());
id(new AphrontNullView())->appendChild($summaries)->render());
$pager = $this->renderOlderPageLink().$this->renderNewerPageLink();
if ($pager) {
@ -224,6 +229,7 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
$phids = array();
foreach ($posts as $post) {
$engine->addObject($post, PhamePost::MARKUP_FIELD_BODY);
$engine->addObject($post, PhamePost::MARKUP_FIELD_SUMMARY);
$phids[] = $post->getBloggerPHID();
}
@ -240,6 +246,7 @@ abstract class PhameBasicBlogSkin extends PhameBlogSkin {
->setSkin($this)
->setPost($post)
->setBody($engine->getOutput($post, PhamePost::MARKUP_FIELD_BODY))
->setSummary($engine->getOutput($post, PhamePost::MARKUP_FIELD_SUMMARY))
->setAuthor($handles[$post->getBloggerPHID()]);
$post->makeEphemeral();

View file

@ -23,6 +23,7 @@ final class PhamePost extends PhameDAO
implements PhabricatorPolicyInterface, PhabricatorMarkupInterface {
const MARKUP_FIELD_BODY = 'markup:body';
const MARKUP_FIELD_SUMMARY = 'markup:summary';
const VISIBILITY_DRAFT = 0;
const VISIBILITY_PUBLISHED = 1;
@ -193,9 +194,13 @@ final class PhamePost extends PhameDAO
public function getMarkupText($field) {
switch ($field) {
case self::MARKUP_FIELD_BODY:
return $this->getBody();
case self::MARKUP_FIELD_SUMMARY:
return PhabricatorMarkupEngine::summarize($this->getBody());
}
}
public function didMarkupText(
$field,

View file

@ -1,100 +0,0 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group phame
*/
final class PhameBlogDetailView extends AphrontView {
private $user;
private $blog;
private $bloggers;
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
private function getUser() {
return $this->user;
}
public function setBloggers(array $bloggers) {
assert_instances_of($bloggers, 'PhabricatorObjectHandle');
$this->bloggers = $bloggers;
return $this;
}
private function getBloggers() {
return $this->bloggers;
}
public function setBlog(PhameBlog $blog) {
$this->blog = $blog;
return $this;
}
private function getBlog() {
return $this->blog;
}
public function render() {
require_celerity_resource('phabricator-remarkup-css');
$user = $this->getUser();
$blog = $this->getBlog();
$bloggers = $this->getBloggers();
$name = phutil_escape_html($blog->getName());
$description = phutil_escape_html($blog->getDescription());
$detail = phutil_render_tag(
'div',
array(
'class' => 'blog-detail'
),
phutil_render_tag(
'div',
array(
'class' => 'header',
),
phutil_render_tag(
'h1',
array(),
$name
)
).
phutil_render_tag(
'div',
array(
'class' => 'description'
),
$description
)
);
return $detail;
}
private function getBloggersHTML(array $bloggers) {
assert_instances_of($bloggers, 'PhabricatorObjectHandle');
$arr = array();
foreach ($bloggers as $blogger) {
$arr[] = '<strong>'.phutil_escape_html($blogger->getName()).'</strong>';
}
return implode(' &middot; ', $arr);
}
}

View file

@ -26,6 +26,8 @@ final class PhamePostView extends AphrontView {
private $viewer;
private $body;
private $skin;
private $summary;
public function setSkin(PhameBlogSkin $skin) {
$this->skin = $skin;
@ -72,6 +74,15 @@ final class PhamePostView extends AphrontView {
return $this->body;
}
public function setSummary($summary) {
$this->summary = $summary;
return $this;
}
public function getSummary() {
return $this->summary;
}
public function renderTitle() {
$href = $this->getSkin()->getURI('post/'.$this->getPost()->getPhameTitle());
return phutil_render_tag(
@ -111,6 +122,15 @@ final class PhamePostView extends AphrontView {
$this->getBody());
}
public function renderSummary() {
return phutil_render_tag(
'div',
array(
'class' => 'phame-post-body',
),
$this->getSummary());
}
public function renderComments() {
$post = $this->getPost();
@ -141,6 +161,18 @@ final class PhamePostView extends AphrontView {
$this->renderComments());
}
public function renderWithSummary() {
return phutil_render_tag(
'div',
array(
'class' => 'phame-post',
),
$this->renderTitle().
$this->renderDatePublished().
$this->renderSummary().
$this->renderComments());
}
private function renderFacebookComments() {
$fb_id = PhabricatorEnv::getEnvConfig('facebook.application-id');
if (!$fb_id) {

View file

@ -495,4 +495,54 @@ final class PhabricatorMarkupEngine {
return $mentions;
}
/**
* Produce a corpus summary, in a way that shortens the underlying text
* without truncating it somewhere awkward.
*
* TODO: We could do a better job of this.
*
* @param string Remarkup corpus to summarize.
* @return string Summarized corpus.
*/
public static function summarize($corpus) {
// Major goals here are:
// - Don't split in the middle of a character (utf-8).
// - Don't split in the middle of, e.g., **bold** text, since
// we end up with hanging '**' in the summary.
// - Try not to pick an image macro, header, embedded file, etc.
// - Hopefully don't return too much text. We don't explicitly limit
// this right now.
$blocks = preg_split("/\n *\n\s*/", trim($corpus));
$best = null;
foreach ($blocks as $block) {
// This is a test for normal spaces in the block, i.e. a heuristic to
// distinguish standard paragraphs from things like image macros. It may
// not work well for non-latin text. We prefer to summarize with a
// paragraph of normal words over an image macro, if possible.
$has_space = preg_match('/\w\s\w/', $block);
// This is a test to find embedded images and headers. We prefer to
// summarize with a normal paragraph over a header or an embedded object,
// if possible.
$has_embed = preg_match('/^[{=]/', $block);
if ($has_space && !$has_embed) {
// This seems like a good summary, so return it.
return $block;
}
if (!$best) {
// This is the first block we found; if everything is garbage just
// use the first block.
$best = $block;
}
}
return $best;
}
}