mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 06:42:42 +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:
parent
83bbad8ba0
commit
44c6109bf2
7 changed files with 99 additions and 105 deletions
|
@ -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',
|
||||
|
|
|
@ -39,6 +39,8 @@ extends PhameController {
|
|||
PhamePost::MARKUP_FIELD_BODY,
|
||||
$user);
|
||||
|
||||
$content = '<div class="phabricator-remarkup">'.$content.'</div>';
|
||||
|
||||
return id(new AphrontAjaxResponse())->setContent($content);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,10 +194,14 @@ final class PhamePost extends PhameDAO
|
|||
|
||||
|
||||
public function getMarkupText($field) {
|
||||
return $this->getBody();
|
||||
switch ($field) {
|
||||
case self::MARKUP_FIELD_BODY:
|
||||
return $this->getBody();
|
||||
case self::MARKUP_FIELD_SUMMARY:
|
||||
return PhabricatorMarkupEngine::summarize($this->getBody());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function didMarkupText(
|
||||
$field,
|
||||
$output,
|
||||
|
|
|
@ -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(' · ', $arr);
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue