EBernhardson has uploaded a new change for review.
https://gerrit.wikimedia.org/r/189909
Change subject: Record topic imports to Special:Log
......................................................................
Record topic imports to Special:Log
Change-Id: I0ce69cca9ab017fc0b9357a65245defd98c71f0f
---
M Flow.php
M autoload.php
M container.php
M i18n/en.json
M i18n/qqq.json
M includes/Import/ImportSource.php
M includes/Import/Importer.php
M includes/Import/LiquidThreadsApi/Objects.php
M includes/Import/Postprocessor/LqtRedirector.php
M includes/Import/Postprocessor/Postprocessor.php
M includes/Import/Postprocessor/ProcessorGroup.php
A includes/Import/Postprocessor/SpecialLogTopic.php
R includes/Log/ActionFormatter.php
A includes/Log/ImportFormatter.php
14 files changed, 213 insertions(+), 28 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Flow
refs/changes/09/189909/1
diff --git a/Flow.php b/Flow.php
index d80b4fd..45b8274 100644
--- a/Flow.php
+++ b/Flow.php
@@ -238,10 +238,11 @@
}
}
// Manually add that more complex actions
-$wgLogActionsHandlers['delete/flow-restore-post'] = 'Flow\Log\Formatter';
-$wgLogActionsHandlers['suppress/flow-restore-post'] = 'Flow\Log\Formatter';
-$wgLogActionsHandlers['delete/flow-restore-topic'] = 'Flow\Log\Formatter';
-$wgLogActionsHandlers['suppress/flow-restore-topic'] = 'Flow\Log\Formatter';
+$wgLogActionsHandlers['delete/flow-restore-post'] = 'Flow\Log\ActionFormatter';
+$wgLogActionsHandlers['suppress/flow-restore-post'] =
'Flow\Log\ActionFormatter';
+$wgLogActionsHandlers['delete/flow-restore-topic'] =
'Flow\Log\ActionFormatter';
+$wgLogActionsHandlers['suppress/flow-restore-topic'] =
'Flow\Log\ActionFormatter';
+$wgLogActionsHandlers['import/lqt-to-flow'] = 'Flow\Log\LqtImportFormatter';
// Register URL actions
foreach( $wgFlowActions as $action => $options ) {
diff --git a/autoload.php b/autoload.php
index b127f6c..95c7ad5 100644
--- a/autoload.php
+++ b/autoload.php
@@ -125,6 +125,7 @@
'Flow\\Exception\\InvalidActionException' => __DIR__ .
'/includes/Exception/ExceptionHandling.php',
'Flow\\Exception\\InvalidDataException' => __DIR__ .
'/includes/Exception/ExceptionHandling.php',
'Flow\\Exception\\InvalidInputException' => __DIR__ .
'/includes/Exception/ExceptionHandling.php',
+ 'Flow\\Exception\\InvalidReferenceException' => __DIR__ .
'/includes/Exception/ExceptionHandling.php',
'Flow\\Exception\\InvalidTopicUuidException' => __DIR__ .
'/includes/Exception/ExceptionHandling.php',
'Flow\\Exception\\NoIndexException' => __DIR__ .
'/includes/Exception/ExceptionHandling.php',
'Flow\\Exception\\NoParsoidException' => __DIR__ .
'/includes/Exception/ExceptionHandling.php',
@@ -212,13 +213,15 @@
'Flow\\Import\\Postprocessor\\PostprocessingException' => __DIR__ .
'/includes/Import/Postprocessor/PostprocessingException.php',
'Flow\\Import\\Postprocessor\\Postprocessor' => __DIR__ .
'/includes/Import/Postprocessor/Postprocessor.php',
'Flow\\Import\\Postprocessor\\ProcessorGroup' => __DIR__ .
'/includes/Import/Postprocessor/ProcessorGroup.php',
+ 'Flow\\Import\\Postprocessor\\SpecialLogTopic' => __DIR__ .
'/includes/Import/Postprocessor/SpecialLogTopic.php',
'Flow\\Import\\TalkpageImportOperation' => __DIR__ .
'/includes/Import/Importer.php',
'Flow\\Import\\TopicImportState' => __DIR__ .
'/includes/Import/Importer.php',
'Flow\\Import\\Wikitext\\ConversionStrategy' => __DIR__ .
'/includes/Import/Wikitext/ConversionStrategy.php',
'Flow\\Import\\Wikitext\\ImportSource' => __DIR__ .
'/includes/Import/Wikitext/ImportSource.php',
'Flow\\LinksTableUpdater' => __DIR__ .
'/includes/LinksTableUpdater.php',
- 'Flow\\Log\\Formatter' => __DIR__ . '/includes/Log/Formatter.php',
+ 'Flow\\Log\\ActionFormatter' => __DIR__ .
'/includes/Log/ActionFormatter.php',
'Flow\\Log\\Logger' => __DIR__ . '/includes/Log/Logger.php',
+ 'Flow\\Log\\LqtImportFormatter' => __DIR__ .
'/includes/Log/ImportFormatter.php',
'Flow\\Log\\PostModerationLogger' => __DIR__ .
'/includes/Log/PostModerationLogger.php',
'Flow\\Model\\AbstractRevision' => __DIR__ .
'/includes/Model/AbstractRevision.php',
'Flow\\Model\\AbstractSummary' => __DIR__ .
'/includes/Model/AbstractSummary.php',
diff --git a/container.php b/container.php
index 7d54a89..f374a5e 100644
--- a/container.php
+++ b/container.php
@@ -1138,13 +1138,19 @@
} );
$c['importer'] = $c->share( function( $c ) {
- return new Flow\Import\Importer(
+ $importer = new Flow\Import\Importer(
$c['storage'],
$c['factory.loader.workflow'],
$c['memcache.buffered'],
$c['db.factory'],
$c['deferred_queue']
);
+
+ $importer->addPostprocessor( new
Flow\Import\Postprocessor\SpecialLogTopic(
+ $c['occupation_controller']->getTalkpageManager()
+ ) );
+
+ return $importer;
} );
return $c;
diff --git a/i18n/en.json b/i18n/en.json
index e7644ed..7eb6dfc 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -21,6 +21,7 @@
"logentry-delete-flow-restore-topic": "$1 {{GENDER:$2|restored}} a [$4
topic] on [[$3]]",
"logentry-suppress-flow-suppress-topic": "$1 {{GENDER:$2|suppressed}} a
[$4 topic] on [[$3]]",
"logentry-suppress-flow-restore-topic": "$1 {{GENDER:$2|deleted}} a [$4
topic] on [[$3]]",
+ "logentry-import-lqt-to-flow": "[[$1|<nowiki>$2</nowiki>]] on [[$3]]
was imported from LiquidThreads to Flow",
"flow-user-moderated": "Moderated user",
"flow-board-header-browse-topics-link": "Browse topics",
"flow-edit-header-link": "Edit header",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index acd6898..97f7118 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -26,6 +26,7 @@
"logentry-delete-flow-restore-topic": "Text for a deletion log entry
when a deleted topic was restored. Parameters:\n* $1 - the user: link to the
user page\n* $2 - the username. Can be used for GENDER.\n* $3 - the page where
the topic was moderated\n* $4 - permalink URL to the moderated
topic\n{{Related|Flow-logentry}}",
"logentry-suppress-flow-suppress-topic": "Text for a deletion log entry
when a topic was suppressed. Parameters:\n* $1 - the user: link to the user
page\n* $2 - the username. Can be used for GENDER.\n* $3 - the page where the
topic was moderated\n* $4 - permalink URL to the moderated
topic\n{{Related|Flow-logentry}}",
"logentry-suppress-flow-restore-topic": "Text for a deletion log entry
when a suppressed topic was restored. Parameters:\n* $1 - the user: link to the
user page\n* $2 - the username. Can be used for GENDER.\n* $3 - the page where
the topic was moderated\n* $4 - permalink URL to the moderated
topic\n{{Related|Flow-logentry}}",
+ "logentry-import-lqt-to-flow": "Text for an import log entry when a
topic has been imported from LiquidThreads to Flow. Parameters:\n* $1 - The
article within the topic namespace the topic was imported to\n* $2 - The board
that was converted from LiquidThreasd to Flow.",
"flow-user-moderated": "Name to display when the current user is not
allowed to see the users name due to moderation",
"flow-board-header-browse-topics-link": "Text to show in the board
header which links to the topics list.",
"flow-edit-header-link": "Used as text for the button that either
allows editing the header in place or brings the user to a page for editing the
header.",
diff --git a/includes/Import/ImportSource.php b/includes/Import/ImportSource.php
index cb0316b..c73bd62 100644
--- a/includes/Import/ImportSource.php
+++ b/includes/Import/ImportSource.php
@@ -62,6 +62,18 @@
* @return IImportSummary|null The summary, if any, for a topic
*/
function getTopicSummary();
+
+ /**
+ * @return string The subtype to use when logging topic imports
+ * to Special:Log. It will appear in the log as "import/$logType"
+ */
+ function getLogType();
+
+ /**
+ * @return string[string] A k/v map of strings containing additional
+ * parameters to be stored with the log about importing this topic.
+ */
+ function getLogParameters();
}
interface IImportHeader extends IRevisionableObject {
diff --git a/includes/Import/Importer.php b/includes/Import/Importer.php
index c8137dd..57637c1 100644
--- a/includes/Import/Importer.php
+++ b/includes/Import/Importer.php
@@ -521,7 +521,7 @@
} catch ( \Exception $e ) {
$state->rollback();
\MWExceptionHandler::logException( $e );
- $state->logger->error( 'Failed importing
header' );
+ $state->logger->error( 'Failed importing
header: ' . $header->getObjectKey() );
$state->logger->error( (string)$e );
$failed++;
}
@@ -543,7 +543,7 @@
} catch ( \Exception $e ) {
$state->rollback();
\MWExceptionHandler::logException( $e );
- $state->logger->error( 'Failed importing topic'
);
+ $state->logger->error( 'Failed importing topic:
' . $topic->getObjectKey() );
$state->logger->error( (string)$e );
$failed++;
}
@@ -610,18 +610,13 @@
$this->importSummary( $topicState, $summary );
}
- try {
- foreach ( $importTopic->getReplies() as $post ) {
- $this->importPost( $topicState, $post,
$topicState->topicTitle );
- }
- } catch ( ImportException $e ) {
- $pageState->logger->error( "Failed while importing
topic " . $importTopic->getObjectKey() );
- throw $e;
+ foreach ( $importTopic->getReplies() as $post ) {
+ $this->importPost( $topicState, $post,
$topicState->topicTitle );
}
$topicState->commitLastModified();
$topicId = $topicState->topicWorkflow->getId();
- $pageState->postprocessor->afterTopicImported( $importTopic,
$topicId );
+ $pageState->postprocessor->afterTopicImported( $topicState,
$importTopic );
}
/**
@@ -813,12 +808,10 @@
$post
);
$state->parent->logger->info( $logPrefix . "Finished
importing post with " . count( $replyRevisions ) . " revisions" );
+ $state->parent->postprocessor->afterPostImported(
$state, $post, $topRevision->getPostId() );
}
$state->recordModificationTime( $topRevision->getRevisionId() );
-
- $topicId = $state->topicWorkflow->getId();
- $state->parent->postprocessor->afterPostImported( $post,
$topicId, $topRevision->getPostId() );
foreach ( $post->getReplies() as $subReply ) {
$this->importPost( $state, $subReply, $topRevision,
$logPrefix . ' ' );
diff --git a/includes/Import/LiquidThreadsApi/Objects.php
b/includes/Import/LiquidThreadsApi/Objects.php
index 2e1a216..3a7b2e6 100644
--- a/includes/Import/LiquidThreadsApi/Objects.php
+++ b/includes/Import/LiquidThreadsApi/Objects.php
@@ -186,6 +186,18 @@
public function getObjectKey() {
return 'topic' . $this->importSource->getObjectKey(
'thread_id', $this->apiResponse['id'] );
}
+
+ public function getLogType() {
+ return "lqt-to-flow";
+ }
+
+ public function getLogParameters() {
+ return array(
+ 'lqt_thread_id' => $this->apiResponse['id'],
+ 'lqt_orig_title' =>
$this->getTitle()->getPrefixedText(),
+ 'lqt_subject' => $this->getText(),
+ );
+ }
}
class ImportSummary extends PageRevisionedObject implements IImportSummary {
diff --git a/includes/Import/Postprocessor/LqtRedirector.php
b/includes/Import/Postprocessor/LqtRedirector.php
index 6553592..ad41ebe 100644
--- a/includes/Import/Postprocessor/LqtRedirector.php
+++ b/includes/Import/Postprocessor/LqtRedirector.php
@@ -6,6 +6,7 @@
use Flow\Import\IImportTopic;
use Flow\Import\LiquidThreadsApi\ImportPost;
use Flow\Import\LiquidThreadsApi\ImportTopic;
+use Flow\Import\TopicImportState;
use Flow\Model\UUID;
use Flow\UrlGenerator;
use Title;
@@ -28,15 +29,22 @@
$this->user = $user;
}
- public function afterTopicImported( IImportTopic $topic, UUID
$newTopicId ) {
+ public function afterTopicImported( TopicImportState $state,
IImportTopic $topic ) {
if ( $topic instanceof ImportTopic /* LQT */ ) {
- $this->redirectsToDo[] = array( $topic->getTitle(),
$newTopicId );
+ $this->redirectsToDo[] = array(
+ $topic->getTitle(),
+ $state->topicWorkflow->getId()
+ );
}
}
- public function afterPostImported( IImportPost $post, UUID $topicId,
UUID $newPostId ) {
+ public function afterPostImported( TopicImportState $state, IImportPost
$post, UUID $newPostId ) {
if ( $post instanceof ImportPost /* LQT */ ) {
- $this->redirectsToDo[] = array( $post->getTitle(),
$topicId, $newPostId );
+ $this->redirectsToDo[] = array(
+ $post->getTitle(),
+ $state->topicWorkflow->getId(),
+ $newPostId
+ );
}
}
diff --git a/includes/Import/Postprocessor/Postprocessor.php
b/includes/Import/Postprocessor/Postprocessor.php
index e511e48..a42d5ee 100644
--- a/includes/Import/Postprocessor/Postprocessor.php
+++ b/includes/Import/Postprocessor/Postprocessor.php
@@ -5,10 +5,11 @@
use Flow\Model\UUID;
use Flow\Import\IImportPost;
use Flow\Import\IImportTopic;
+use Flow\Import\TopicImportState;
interface Postprocessor {
- function afterTopicImported( IImportTopic $topic, UUID $newTopicId );
- function afterPostImported( IImportPost $post, UUID $topicId, UUID
$newPostId );
+ function afterTopicImported( TopicImportState $state, IImportTopic
$topic );
+ function afterPostImported( TopicImportState $state, IImportPost $post,
UUID $newPostId );
function afterTalkpageImported();
function talkpageImportAborted();
}
diff --git a/includes/Import/Postprocessor/ProcessorGroup.php
b/includes/Import/Postprocessor/ProcessorGroup.php
index 1f5b3b5..abfa11a 100644
--- a/includes/Import/Postprocessor/ProcessorGroup.php
+++ b/includes/Import/Postprocessor/ProcessorGroup.php
@@ -5,6 +5,7 @@
use Flow\Model\UUID;
use Flow\Import\IImportPost;
use Flow\Import\IImportTopic;
+use Flow\Import\TopicImportState;
class ProcessorGroup implements Postprocessor {
/** @var array<Postprocessor> **/
@@ -18,11 +19,11 @@
$this->processors[] = $proc;
}
- public function afterTopicImported( IImportTopic $topic, UUID
$newTopicId ) {
+ public function afterTopicImported( TopicImportState $state,
IImportTopic $topic ) {
$this->call( 'afterTopicImported', func_get_args() );
}
- public function afterPostImported( IImportPost $post, UUID $topicId,
UUID $postId ) {
+ public function afterPostImported( TopicImportState $state, IImportPost
$post, UUID $newPostId ) {
$this->call( 'afterPostImported', func_get_args() );
}
diff --git a/includes/Import/Postprocessor/SpecialLogTopic.php
b/includes/Import/Postprocessor/SpecialLogTopic.php
new file mode 100644
index 0000000..c2d8ad8
--- /dev/null
+++ b/includes/Import/Postprocessor/SpecialLogTopic.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Flow\Import\Postprocessor;
+
+use Flow\Data\ManagerGroup;
+use Flow\Exception\FlowException;
+use Flow\Import\IImportPost;
+use Flow\Import\IImportTopic;
+use Flow\Import\TopicImportState;
+use Flow\Model\UUID;
+use Flow\Model\Workflow;
+use ManualLogEntry;
+use User;
+
+/**
+ * Records topic imports to Special:Log.
+ */
+class SpecialLogTopic implements PostProcessor {
+ /**
+ * @var array A set of topics queue'd up to be logged once
+ * the current db transaction completes.
+ */
+ protected $queue = array();
+
+ /**
+ * @var array Map from topic alphadecimal uuid to a list of post UUID's
imported
+ * in this run.
+ */
+ protected $imported = array();
+
+ /**
+ * @var User The user to attribute logs to
+ */
+ protected $user;
+
+ public function __construct( User $user ) {
+ $this->user = $user;
+ }
+
+ public function afterTopicImported( TopicImportState $state,
IImportTopic $topic ) {
+ $alpha = $state->topicWorkflow->getId()->getAlphadecimal();
+ // If no posts were imported within this topic, then nothing to
report
+ if ( !isset( $this->imported[$alpha] ) ) {
+ return;
+ }
+
+ // queue up topics to be inserted to special:log
+ $this->queue[] = array(
+ $state->topicWorkflow,
+ $topic,
+ );
+
+ // reset the import state
+ unset( $this->imported[$alpha] );
+ }
+
+ public function afterPostImported( TopicImportState $state, IImportPost
$post, UUID $newPostId ) {
+ $alpha = $state->topicWorkflow->getId()->getAlphadecimal();
+ $this->imported[$alpha] = true;
+ }
+
+ public function afterTalkpageImported() {
+ // this method is slightly mislabeled. It is called
+ // just after every commit which is done once for
+ // the board header and once for each contained topic.
+ foreach ( $this->queue as $args ) {
+ $this->logTopicImport( $args[0], $args[1] );
+ }
+ $this->queue = array();
+ }
+
+ public function talkpageImportAborted() {
+ // drop anything queue'd up
+ $this->queue = array();
+ $this->imported = array();
+ }
+
+ protected function logTopicImport( Workflow $workflow, IImportTopic
$topic ) {
+ $logEntry = new ManualLogEntry( "import", $topic->getLogType()
);
+ $logEntry->setTarget( $workflow->getOwnerTitle() );
+ $logEntry->setPerformer( $this->user );
+ $logEntry->setParameters( array(
+ 'topic' =>
$workflow->getArticleTitle()->getPrefixedText(),
+ ) + $topic->getLogParameters() );
+ $logEntry->setComment( "@todo create i18n message for reason" );
+ $logEntry->insert();
+ }
+}
diff --git a/includes/Log/Formatter.php b/includes/Log/ActionFormatter.php
similarity index 98%
rename from includes/Log/Formatter.php
rename to includes/Log/ActionFormatter.php
index b4e8461..b56bb17 100644
--- a/includes/Log/Formatter.php
+++ b/includes/Log/ActionFormatter.php
@@ -6,7 +6,7 @@
use Flow\Parsoid\Utils;
use Message;
-class Formatter extends \LogFormatter {
+class ActionFormatter extends \LogFormatter {
/**
* Formats an activity log entry.
*
diff --git a/includes/Log/ImportFormatter.php b/includes/Log/ImportFormatter.php
new file mode 100644
index 0000000..91f82e1
--- /dev/null
+++ b/includes/Log/ImportFormatter.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Flow\Log;
+
+use Flow\Container;
+use Flow\Model\UUID;
+use Flow\Parsoid\Utils;
+use Message;
+use Title;
+
+class LqtImportFormatter extends \LogFormatter {
+
+ public function getPreloadTitles() {
+ $titles = array( $this->entry->getTarget() );
+ $params = $this->entry->getParameters();
+ $topic = Title::newFromText( $params['topic'] );
+ if ( $topic ) {
+ $titles[] = $topic;
+ }
+
+ return $titles;
+ }
+
+ /**
+ * Formats an activity log entry.
+ *
+ * @return string The log entry
+ */
+ protected function getActionMessage() {
+ global $wgContLang;
+
+ $board = $this->entry->getTarget();
+ $params = $this->entry->getParameters();
+ $topic = Title::newFromText( $params['topic'] );
+
+ $skin = $this->plaintext ? null : $this->context->getSkin();
+ $language = $skin === null ? $wgContLang : $skin->getLanguage();
+ // Give grep a chance to find the usages:
+ // logentry-import-lqt-to-flow
+ $message = wfMessage( "logentry-import-lqt-to-flow" )
+ ->params(
+ $topic ? $topic->getPrefixedText() : '',
+ isset( $params['lqt_subject'] ) ?
$params['lqt_subject'] : '',
+ $board->getPrefixedText()
+ )
+ ->inLanguage( $language );
+
+ if ( $this->plaintext ) {
+ return $message;
+ } else {
+ return \Html::rawElement(
+ 'span',
+ array( 'class' => 'plainlinks' ),
+ $message->parse()
+ );
+ }
+ }
+}
--
To view, visit https://gerrit.wikimedia.org/r/189909
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0ce69cca9ab017fc0b9357a65245defd98c71f0f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: EBernhardson <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits