From 9660d42713596b524d5d4cb5108bb3ec8e6872c5 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 4 Mar 2008 02:03:52 +0000 Subject: [PATCH] Some experimental support for including upload data in XML export, as specced. Usable with --uploads option on dumpBackups.php Some issues: * doesn't respond to the current v full-history modes * won't pick up file entries with no corresponding page * on default config, you may end up with 'localhost' in URLs :P * synchronization and mutability problems ** DB lookups are made in the middle of the dump and may not be in sync with state at the beginning of the dump. ** URL to current version at time of dump could point to a different, future version in future --- includes/Export.php | 73 +++++++++++++++++++++++++++++++------- maintenance/backup.inc | 2 ++ maintenance/dumpBackup.php | 2 ++ 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/includes/Export.php b/includes/Export.php index 69d88fc6bd..47a8823526 100644 --- a/includes/Export.php +++ b/includes/Export.php @@ -25,6 +25,8 @@ class WikiExporter { var $list_authors = false ; # Return distinct author list (when not returning full history) var $author_list = "" ; + + var $dumpUploads = false; const FULL = 0; const CURRENT = 1; @@ -263,7 +265,11 @@ class WikiExporter { $last->page_namespace != $row->page_namespace || $last->page_title != $row->page_title ) { if( isset( $last ) ) { - $output = $this->writer->closePage(); + $output = ''; + if( $this->dumpUploads ) { + $output .= $this->writer->writeUploads( $last ); + } + $output .= $this->writer->closePage(); $this->sink->writeClosePage( $output ); } $output = $this->writer->openPage( $row ); @@ -274,7 +280,12 @@ class WikiExporter { $this->sink->writeRevision( $row, $output ); } if( isset( $last ) ) { - $output = $this->author_list . $this->writer->closePage(); + $output = ''; + if( $this->dumpUploads ) { + $output .= $this->writer->writeUploads( $last ); + } + $output .= $this->author_list; + $output .= $this->writer->closePage(); $this->sink->writeClosePage( $output ); } $resultset->free(); @@ -415,20 +426,12 @@ class XmlDumpWriter { $out = " \n"; $out .= " " . wfElement( 'id', null, strval( $row->rev_id ) ) . "\n"; - $ts = wfTimestamp( TS_ISO_8601, $row->rev_timestamp ); - $out .= " " . wfElement( 'timestamp', null, $ts ) . "\n"; + $out .= $this->writeTimestamp( $row->rev_timestamp ); if( $row->rev_deleted & Revision::DELETED_USER ) { $out .= " " . wfElement( 'contributor', array( 'deleted' => 'deleted' ) ) . "\n"; } else { - $out .= " \n"; - if( $row->rev_user ) { - $out .= " " . wfElementClean( 'username', null, strval( $row->rev_user_text ) ) . "\n"; - $out .= " " . wfElement( 'id', null, strval( $row->rev_user ) ) . "\n"; - } else { - $out .= " " . wfElementClean( 'ip', null, strval( $row->rev_user_text ) ) . "\n"; - } - $out .= " \n"; + $out .= $this->writeContributor( $row->rev_user, $row->rev_user_text ); } if( $row->rev_minor_edit ) { @@ -460,6 +463,52 @@ class XmlDumpWriter { wfProfileOut( $fname ); return $out; } + + function writeTimestamp( $timestamp ) { + $ts = wfTimestamp( TS_ISO_8601, $timestamp ); + return " " . wfElement( 'timestamp', null, $ts ) . "\n"; + } + + function writeContributor( $id, $text ) { + $out = " \n"; + if( $id ) { + $out .= " " . wfElementClean( 'username', null, strval( $text ) ) . "\n"; + $out .= " " . wfElement( 'id', null, strval( $id ) ) . "\n"; + } else { + $out .= " " . wfElementClean( 'ip', null, strval( $text ) ) . "\n"; + } + $out .= " \n"; + return $out; + } + + /** + * Warning! This data is potentially inconsistent. :( + */ + function writeUploads( $row ) { + if( $row->page_namespace == NS_IMAGE ) { + $img = wfFindFile( $row->page_title ); + if( $img ) { + $out = ''; + foreach( array_reverse( $img->getHistory() ) as $ver ) { + $out .= $this->writeUpload( $ver ); + } + $out .= $this->writeUpload( $img ); + return $out; + } + } + return ''; + } + + function writeUpload( $file ) { + return " \n" . + $this->writeTimestamp( $file->getTimestamp() ) . + $this->writeContributor( $file->getUser( 'id' ), $file->getUser( 'text' ) ) . + " " . wfElementClean( 'comment', null, $file->getDescription() ) . "\n" . + " " . wfElement( 'filename', null, $file->getName() ) . "\n" . + " " . wfElement( 'src', null, $file->getFullUrl() ) . "\n" . + " " . wfElement( 'size', null, $file->getSize() ) . "\n" . + " \n"; + } } diff --git a/maintenance/backup.inc b/maintenance/backup.inc index 94fb48c9ae..3fcb981119 100644 --- a/maintenance/backup.inc +++ b/maintenance/backup.inc @@ -40,6 +40,7 @@ class BackupDumper { var $endId = 0; var $sink = null; // Output filters var $stubText = false; // include rev_text_id instead of text; for 2-pass dump + var $dumpUploads = false; function BackupDumper( $args ) { $this->stderr = fopen( "php://stderr", "wt" ); @@ -177,6 +178,7 @@ class BackupDumper { $db = $this->backupDb(); $exporter = new WikiExporter( $db, $history, WikiExporter::STREAM, $text ); + $exporter->dumpUploads = $this->dumpUploads; $wrapper = new ExportProgressFilter( $this->sink, $this ); $exporter->setOutputSink( $wrapper ); diff --git a/maintenance/dumpBackup.php b/maintenance/dumpBackup.php index 9ec5674d45..6590fd4894 100644 --- a/maintenance/dumpBackup.php +++ b/maintenance/dumpBackup.php @@ -54,6 +54,7 @@ if( isset( $options['end'] ) ) { } $dumper->skipHeader = isset( $options['skip-header'] ); $dumper->skipFooter = isset( $options['skip-footer'] ); +$dumper->dumpUploads = isset( $options['uploads'] ); $textMode = isset( $options['stub'] ) ? WikiExporter::STUB : WikiExporter::TEXT; @@ -83,6 +84,7 @@ Options: --skip-header Don't output the header --skip-footer Don't output the footer --stub Don't perform old_text lookups; for 2-pass dump + --uploads Include upload records (experimental) Fancy stuff: --plugin=[:] Load a dump plugin class -- 2.20.1