Mattflaschen has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/202979

Change subject: WIP: LQT maintenance refactoring
......................................................................

WIP: LQT maintenance refactoring

Change-Id: Idb4c95d189c6de3df3a0c5103a619c7844296b20
---
M includes/Import/Converter.php
M includes/Import/LiquidThreadsApi/Objects.php
M maintenance/convertLqt.php
D maintenance/convertLqtPage.php
A maintenance/convertLqtPageFromRemoteApiForTesting.php
A maintenance/convertLqtPageOnLocalWiki.php
M maintenance/convertNamespaceFromWikitext.php
M tests/phpunit/Import/ConverterTest.php
8 files changed, 190 insertions(+), 141 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Flow 
refs/changes/79/202979/1

diff --git a/includes/Import/Converter.php b/includes/Import/Converter.php
index b24bf2d..f689816 100644
--- a/includes/Import/Converter.php
+++ b/includes/Import/Converter.php
@@ -34,7 +34,7 @@
         * @var DatabaseBase Slave database of the current wiki. Required
         *  to lookup past page moves.
         */
-       protected $dbr;
+       protected $dbw;
 
        /**
         * @var Importer Service capable of turning an IImportSource into
@@ -61,7 +61,7 @@
        protected $strategy;
 
        /**
-        * @param DatabaseBase $dbr Slave wiki database to read from
+        * @param DatabaseBase $dbw Master wiki database to read from
         * @param Importer $importer
         * @param LoggerInterface $logger
         * @param User $user Administrative user for moves and edits related
@@ -70,7 +70,7 @@
         * @throws ImportException When $user does not have an Id
         */
        public function __construct(
-               DatabaseBase $dbr,
+               DatabaseBase $dbw,
                Importer $importer,
                LoggerInterface $logger,
                User $user,
@@ -79,7 +79,7 @@
                if ( !$user->getId() ) {
                        throw new ImportException( 'User must have id' );
                }
-               $this->dbr = $dbr;
+               $this->dbw = $dbw;
                $this->importer = $importer;
                $this->logger = $logger;
                $this->user = $user;
@@ -186,7 +186,7 @@
         * @return Title|null
         */
        protected function getPageMovedFrom( Title $title ) {
-               $row = $this->dbr->selectRow(
+               $row = $this->dbw->selectRow(
                        array( 'logging', 'page' ),
                        array( 'log_namespace', 'log_title', 'log_user' ),
                        array(
diff --git a/includes/Import/LiquidThreadsApi/Objects.php 
b/includes/Import/LiquidThreadsApi/Objects.php
index 7bd7dc9..9517bd4 100644
--- a/includes/Import/LiquidThreadsApi/Objects.php
+++ b/includes/Import/LiquidThreadsApi/Objects.php
@@ -317,7 +317,7 @@
 class MovedImportPost extends ImportPost {
        public function getRevisions() {
                $factory = function( $data, $parent ) {
-                       return new MovedImportRevision( $data, $parent );
+                       return new MovedImportRevision( $data, $parent, 
$this->importSource->getScriptUser() );
                };
                $pageData = $this->importSource->getPageData( $this->pageId );
                return new RevisionIterator( $pageData, $this, $factory );
diff --git a/maintenance/convertLqt.php b/maintenance/convertLqt.php
index a4b7521..cef22d1 100644
--- a/maintenance/convertLqt.php
+++ b/maintenance/convertLqt.php
@@ -22,38 +22,34 @@
                parent::__construct();
                $this->mDescription = "Converts LiquidThreads data to Flow 
data";
                $this->addOption( 'logfile', 'File to read and store 
associations between imported items and their sources. This is required for the 
import to be idempotent.', true, true );
-               $this->addOption( 'verbose', 'Report on import progress to 
stdout' );
                $this->addOption( 'debug', 'Include debug information with 
progress report' );
                $this->addOption( 'startId', 'Page id to start importing at 
(inclusive)' );
                $this->addOption( 'stopId', 'Page id to stop importing at 
(exclusive)' );
        }
 
        public function execute() {
-               if ( $this->getOption( 'verbose' ) ) {
-                       $logger = new MaintenanceDebugLogger( $this );
-                       if ( $this->getOption( 'debug' ) ) {
-                               $logger->setMaximumLevel( LogLevel::DEBUG );
-                       } else {
-                               $logger->setMaximumLevel( LogLevel::INFO );
-                       }
+               $logger = new MaintenanceDebugLogger( $this );
+               if ( $this->getOption( 'debug' ) ) {
+                       $logger->setMaximumLevel( LogLevel::DEBUG );
                } else {
-                       $logger = new NullLogger;
+                       $logger->setMaximumLevel( LogLevel::INFO );
                }
+
                $importer = Flow\Container::get( 'importer' );
                $talkpageManagerUser = 
FlowHooks::getOccupationController()->getTalkpageManager();
 
+               $dbw = wfGetDB( DB_MASTER );
                $strategy = new ConversionStrategy(
-                       wfGetDB( DB_MASTER ),
+                       $dbw
                        new FileImportSourceStore( $this->getOption( 'logfile' 
) ),
                        new LocalApiBackend( $talkpageManagerUser ),
                        Container::get( 'url_generator' ),
                        $talkpageManagerUser,
-                       Container::get( 'controller.notifications' )
+                       Container::get( 'controller.notification' )
                );
 
-               $dbr = wfGetDB( DB_SLAVE );
                $converter = new \Flow\Import\Converter(
-                       $dbr,
+                       $dbw,
                        $importer,
                        $logger,
                        $talkpageManagerUser,
@@ -64,6 +60,7 @@
                $stopId = $this->getOption( 'stopId' );
 
                $logger->info( "Starting full wiki LQT conversion" );
+               $dbr = wfGetDB( DB_SLAVE );
                $titles = new PagesWithPropertyIterator( $dbr, 
'use-liquid-threads', $startId, $stopId );
                $converter->convert( $titles );
        }
diff --git a/maintenance/convertLqtPage.php b/maintenance/convertLqtPage.php
deleted file mode 100644
index a6bcf02..0000000
--- a/maintenance/convertLqtPage.php
+++ /dev/null
@@ -1,113 +0,0 @@
-<?php
-
-use Flow\Import\FileImportSourceStore;
-use Flow\Import\NullImportSourceStore;
-use Flow\Import\LiquidThreadsApi\LocalApiBackend;
-use Flow\Import\LiquidThreadsApi\RemoteApiBackend;
-use Flow\Import\LiquidThreadsApi\ImportSource as LiquidThreadsApiImportSource;
-use Flow\Import\Postprocessor\LqtRedirector;
-use Flow\Import\Postprocessor\LqtNotifications;
-use Psr\Log\LogLevel;
-
-require_once ( getenv( 'MW_INSTALL_PATH' ) !== false
-       ? getenv( 'MW_INSTALL_PATH' ) . '/maintenance/Maintenance.php'
-       : dirname( __FILE__ ) . '/../../../maintenance/Maintenance.php' );
-
-class ConvertLqtPage extends Maintenance {
-       public function __construct() {
-               parent::__construct();
-               $this->mDescription = "Converts LiquidThreads data to Flow 
data";
-               $this->addArg( 'dstpage', 'Page name of the local page to 
import to', true );
-               $this->addOption( 'srcpage', 'Page name of the remote page to 
import from. If not specified defaults to dstpage', false, true );
-               $this->addOption( 'remoteapi', 'Remote API URL to read from', 
false, true );
-               $this->addOption( 'cacheremoteapidir', 'Cache remote api calls 
to the specified directory', false, true );
-               $this->addOption( 'logfile', 'File to read and store 
associations between imported items and their sources', false, true );
-               $this->addOption( 'verbose', 'Report on import progress to 
stdout' );
-               $this->addOption( 'debug', 'Include debug information to 
progress report' );
-               $this->addOption( 'allowunknownusernames', 'Allow import of 
usernames that do not exist on this wiki.  DO NOT USE IN PRODUCTION. This 
simplifies testing imports of production data to a test wiki' );
-               $this->addOption( 'redirect', 'Add redirects from LQT posts to 
their Flow equivalents and update watchlists' );
-               $this->addOption( 'convertnotifications', 'Convert LQT 
notifications into Echo notifications' );
-       }
-
-       public function execute() {
-               $dstPageName = $srcPageName = $this->getArg( 0 );
-
-               if ( $this->hasOption( 'srcpage' ) ) {
-                       $srcPageName = $this->getOption( 'srcpage' );
-               }
-
-               if ( $this->hasOption( 'remoteapi' ) ) {
-                       if ( $this->hasOption( 'cacheremoteapidir' ) ) {
-                               $cacheDir = $this->getOption( 
'cacheremoteapidir' );
-                               if ( !is_dir( $cacheDir ) ) {
-                                       if ( !mkdir( $cacheDir ) ) {
-                                               throw new 
Flow\Exception\FlowException( 'Provided dir for caching remote api calls is not 
creatable.' );
-                                       }
-                               }
-                               if ( !is_writable( $cacheDir ) ) {
-                                       throw new Flow\Exception\FlowException( 
'Provided dir for caching remote api calls is not writable.' );
-                               }
-                       } else {
-                               $cacheDir = null;
-                       }
-                       $api = new RemoteApiBackend( $this->getOption( 
'remoteapi' ), $cacheDir );
-               } else {
-                       $api = new LocalApiBackend;
-               }
-
-               $importer = Flow\Container::get( 'importer' );
-               if ( $this->getOption( 'allowunknownusernames' ) ) {
-                       $importer->setAllowUnknownUsernames( true );
-               }
-               $source = new LiquidThreadsApiImportSource(
-                       $api,
-                       $srcPageName,
-                       
\FlowHooks::getOccupationController()->getTalkpageManager()
-               );
-               $title = Title::newFromText( $dstPageName );
-
-               if ( $this->hasOption( 'logfile' ) ) {
-                       $filename = $this->getOption( 'logfile' );
-                       $sourceStore = new FileImportSourceStore( $filename );
-               } else {
-                       $sourceStore = new NullImportSourceStore;
-               }
-
-               if ( $this->hasOption( 'redirect' ) ) {
-                       if ( $this->hasOption( 'remoteapi' ) ) {
-                               $this->error( 'Cannot use remoteapi and 
redirect together', true );
-                       }
-
-                       $urlGenerator = Flow\Container::get( 'url_generator' );
-                       $user = Flow\Container::get( 'occupation_controller' 
)->getTalkpageManager();
-                       $redirector = new LqtRedirector( $urlGenerator, $user );
-                       $importer->addPostprocessor( $redirector );
-               }
-
-               if ( $this->hasOption( 'convertnotifications' ) ) {
-                       $importer->addPostprocessor( new LqtNotifications(
-                               Flow\Container::get( 'controller.notification' 
),
-                               wfGetDB( DB_MASTER )
-                       ) );
-               }
-
-               if ( $this->getOption( 'verbose' ) ) {
-                       $logger = new MaintenanceDebugLogger( $this );
-                       if ( $this->getOption( 'debug' ) ) {
-                               $logger->setMaximumLevel( LogLevel::DEBUG );
-                       } else {
-                               $logger->setMaximumLevel( LogLevel::INFO );
-                       }
-                       $importer->setLogger( $logger );
-                       $api->setLogger( $logger );
-                       $logger->info( "Starting LQT import from $srcPageName 
to $dstPageName" );
-               }
-
-               $importer->import( $source, $title, $sourceStore );
-
-               $sourceStore->save();
-       }
-}
-
-$maintClass = "ConvertLqtPage";
-require_once ( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/convertLqtPageFromRemoteApiForTesting.php 
b/maintenance/convertLqtPageFromRemoteApiForTesting.php
new file mode 100644
index 0000000..d98f4d3
--- /dev/null
+++ b/maintenance/convertLqtPageFromRemoteApiForTesting.php
@@ -0,0 +1,87 @@
+<?php
+
+use Flow\Import\FileImportSourceStore;
+use Flow\Import\LiquidThreadsApi\BaseConversionStrategy as 
LiquidThreadsApiBaseConversionStrategy;
+use Flow\Import\LiquidThreadsApi\RemoteConversionStrategy as 
LiquidThreadsApiRemoteConversionStrategy;
+use Flow\Import\LiquidThreadsApi\LocalApiBackend;
+use Flow\Import\LiquidThreadsApi\RemoteApiBackend;
+use Flow\Import\LiquidThreadsApi\ImportSource as LiquidThreadsApiImportSource;
+use Flow\Import\Postprocessor\LqtRedirector;
+use Flow\Import\Postprocessor\LqtNotifications;
+use Psr\Log\LogLevel;
+
+require_once ( getenv( 'MW_INSTALL_PATH' ) !== false
+       ? getenv( 'MW_INSTALL_PATH' ) . '/maintenance/Maintenance.php'
+       : dirname( __FILE__ ) . '/../../../maintenance/Maintenance.php' );
+
+/**
+ * This is *only* for use in testing, not production.  The primary purpose is 
to exercise
+ * the API (production also uses the API, but with FauxRequest) and Parsoid.
+ *
+ * This also does not test redirects or notification conversion.
+ */
+class ConvertLqtPageFromRemoteApiForTesting extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->mDescription = "Converts LiquidThreads data to Flow 
data.  Destination page is determined by ConversionStrategy";
+               $this->addOption( 'dstpage', 'Page name of the destination page 
on the current wiki.  Defaults to same as source', false, true );
+               $this->addOption( 'srcpage', 'Page name of the source page to 
import from.', true, true );
+               $this->addOption( 'remoteapi', 'Remote API URL to read from', 
true, true );
+               $this->addOption( 'cacheremoteapidir', 'Cache remote api calls 
to the specified directory', true, true );
+               $this->addOption( 'logfile', 'File to read and store 
associations between imported items and their sources', true, true );
+               $this->addOption( 'debug', 'Include debug information to 
progress report' );
+       }
+
+       public function execute() {
+               $cacheDir = $this->getOption( 'cacheremoteapidir' );
+               if ( !is_dir( $cacheDir ) ) {
+                       if ( !mkdir( $cacheDir ) ) {
+                               throw new Flow\Exception\FlowException( 
'Provided dir for caching remote api calls is not creatable.' );
+                       }
+               }
+               if ( !is_writable( $cacheDir ) ) {
+                       throw new Flow\Exception\FlowException( 'Provided dir 
for caching remote api calls is not writable.' );
+               }
+
+               $api = new RemoteApiBackend( $this->getOption( 'remoteapi' ), 
$cacheDir );
+
+               $importer = Flow\Container::get( 'importer' );
+               $importer->setAllowUnknownUsernames( true );
+
+               $talkPageManagerUser = 
\FlowHooks::getOccupationController()->getTalkpageManager();
+               
+               $srcPageName = $this->getOption( 'srcpage' );
+               if ( $this->hasOption( 'dstpage' ) ) {
+                       $dstPageName = $this->getOption( 'dstpage' );
+               } else {
+                       $dstPageName = $srcPageName;
+               }
+               
+               $dstTitle = Title::newFromText( $dstPageName );
+               $source = new LiquidThreadsApiImportSource(
+                       $api,
+                       $srcPageName,
+                       $talkPageManagerUser
+               );
+
+               $logFilename = $this->getOption( 'logfile' );
+               $sourceStore = new FileImportSourceStore( $logFilename );
+
+               $logger = new MaintenanceDebugLogger( $this );
+               if ( $this->getOption( 'debug' ) ) {
+                       $logger->setMaximumLevel( LogLevel::DEBUG );
+               } else {
+                       $logger->setMaximumLevel( LogLevel::INFO );
+               }
+
+               $importer->setLogger( $logger );
+               $api->setLogger( $logger );
+
+               $logger->info( "Starting LQT conversion of page $srcPageName" );
+
+               $importer->import( $source, $dstTitle, $sourceStore );
+       }
+}
+
+$maintClass = "ConvertLqtPageFromRemoteApiForTesting";
+require_once ( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/convertLqtPageOnLocalWiki.php 
b/maintenance/convertLqtPageOnLocalWiki.php
new file mode 100644
index 0000000..e4a4fec
--- /dev/null
+++ b/maintenance/convertLqtPageOnLocalWiki.php
@@ -0,0 +1,81 @@
+<?php
+
+use Flow\Container;
+use Flow\Import\FileImportSourceStore;
+use Flow\Import\NullImportSourceStore;
+use Flow\Import\LiquidThreadsApi\ConversionStrategy as 
LiquidThreadsApiConversionStrategy;
+use Flow\Import\LiquidThreadsApi\LocalApiBackend;
+use Flow\Import\LiquidThreadsApi\RemoteApiBackend;
+use Flow\Import\LiquidThreadsApi\ImportSource as LiquidThreadsApiImportSource;
+use Flow\Import\Postprocessor\LqtRedirector;
+use Flow\Import\Postprocessor\LqtNotifications;
+use Psr\Log\LogLevel;
+
+require_once ( getenv( 'MW_INSTALL_PATH' ) !== false
+       ? getenv( 'MW_INSTALL_PATH' ) . '/maintenance/Maintenance.php'
+       : dirname( __FILE__ ) . '/../../../maintenance/Maintenance.php' );
+
+/**
+ * This is intended for use both in testing and in production.  It converts a 
single LQT
+ * page on the current wiki to a Flow page on the current wiki, handling 
archiving.
+ */
+class ConvertLqtPageOnLocalWiki extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->mDescription = "Converts LiquidThreads data to Flow 
data.  Destination page is determined by ConversionStrategy";
+               $this->addOption( 'srcpage', 'Page name of the source page to 
import from.', true, true );
+               $this->addOption( 'logfile', 'File to read and store 
associations between imported items and their sources', true, true );
+               $this->addOption( 'debug', 'Include debug information to 
progress report' );
+       }
+
+       public function execute() {
+               $talkPageManagerUser = 
\FlowHooks::getOccupationController()->getTalkpageManager();
+
+               $api = new LocalApiBackend( $talkPageManagerUser );
+
+               $importer = Container::get( 'importer' );
+
+               $srcPageName = $this->getOption( 'srcpage' );
+               
+               $logFilename = $this->getOption( 'logfile' );
+               $sourceStore = new FileImportSourceStore( $logFilename );
+               
+               $dbw = wfGetDB( DB_MASTER );
+
+               $logger = new MaintenanceDebugLogger( $this );
+               if ( $this->getOption( 'debug' ) ) {
+                       $logger->setMaximumLevel( LogLevel::DEBUG );
+               } else {
+                       $logger->setMaximumLevel( LogLevel::INFO );
+               }
+
+               $strategy = new LiquidThreadsApiConversionStrategy(
+                       $dbw,
+                       $sourceStore,
+                       $api,
+                       Container::get( 'url_generator' ),
+                       $talkPageManagerUser,
+                       Container::get( 'controller.notification' )
+               );
+
+               $importer->setLogger( $logger );
+               $api->setLogger( $logger );
+
+               $converter = new \Flow\Import\Converter(
+                       $dbw,
+                       $importer,
+                       $logger,
+                       $talkPageManagerUser,
+                       $strategy
+               );
+
+               $logger->info( "Starting LQT conversion of page $srcPageName" );
+
+               $converter->convert( new ArrayIterator( array(
+                       \Title::newFromText( $srcPageName ),
+               ) ) );
+       }
+}
+
+$maintClass = "ConvertLqtPageOnLocalWiki";
+require_once ( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/convertNamespaceFromWikitext.php 
b/maintenance/convertNamespaceFromWikitext.php
index 297e05c..10bb95a 100644
--- a/maintenance/convertNamespaceFromWikitext.php
+++ b/maintenance/convertNamespaceFromWikitext.php
@@ -17,7 +17,6 @@
                parent::__construct();
                $this->mDescription = "Converts a single namespace of wikitext 
talk pages to Flow";
                $this->addArg( 'namespace', 'Name of the namespace to convert' 
);
-               $this->addOption( 'verbose', 'Report on import progress to 
stdout' );
        }
 
        public function execute() {
@@ -31,13 +30,11 @@
                }
 
                // @todo send to prod logger?
-               $logger = $this->getOption( 'verbose' )
-                       ? new MaintenanceDebugLogger( $this )
-                       : new NullLogger();
+               $logger = new MaintenanceDebugLogger( $this );
 
-               $dbr = wfGetDB( DB_SLAVE );
+               $dbw = wfGetDB( DB_MASTER );
                $converter = new \Flow\Import\Converter(
-                       $dbr,
+                       $dbw,
                        Flow\Container::get( 'importer' ),
                        $logger,
                        
FlowHooks::getOccupationController()->getTalkpageManager(),
@@ -51,6 +48,7 @@
                $logger->info( "Starting conversion of $namespaceName 
namespace" );
 
                // Iterate over all existing pages of the namespace.
+               $dbr = wfGetDB( DB_SLAVE );
                $it = new NamespaceIterator( $dbr, $namespace );
                // NamespaceIterator is an IteratorAggregate. Get an Iterator
                // so we can wrap that.
@@ -76,4 +74,3 @@
 
 $maintClass = "ConvertNamespaceFromWikitext";
 require_once ( RUN_MAINTENANCE_IF_MAIN );
-
diff --git a/tests/phpunit/Import/ConverterTest.php 
b/tests/phpunit/Import/ConverterTest.php
index e5cbb07..005a980 100644
--- a/tests/phpunit/Import/ConverterTest.php
+++ b/tests/phpunit/Import/ConverterTest.php
@@ -80,14 +80,14 @@
        }
 
        protected function createConverter(
-               DatabaseBase $dbr = null,
+               DatabaseBase $dbw = null,
                Importer $importer = null,
                LoggerInterface $logger = null,
                User $user = null,
                IConversionStrategy $strategy = null
        ) {
                return new Converter(
-                       $dbr ?: wfGetDB( DB_SLAVE ),
+                       $dbw ?: wfGetDB( DB_MASTER ),
                        $importer ?: $this->getMockBuilder( 
'Flow\Import\Importer' )
                                ->disableOriginalConstructor()
                                ->getMock(),

-- 
To view, visit https://gerrit.wikimedia.org/r/202979
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idb4c95d189c6de3df3a0c5103a619c7844296b20
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: Mattflaschen <mflasc...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to