https://www.mediawiki.org/wiki/Special:Code/MediaWiki/113194

Revision: 113194
Author:   maxsem
Date:     2012-03-06 22:59:41 +0000 (Tue, 06 Mar 2012)
Log Message:
-----------
Committing work in progress: plan B for mobile app, action=mobileview (any 
ideas of better name???). Always parses whole wikitext even if it has to return 
just one section, unlike action=parse. Because results are cached, it's also 
faster than one-section action=parse.

Modified Paths:
--------------
    trunk/extensions/MobileFrontend/MobileFrontend.php

Added Paths:
-----------
    trunk/extensions/MobileFrontend/api/ApiMobileView.php

Modified: trunk/extensions/MobileFrontend/MobileFrontend.php
===================================================================
--- trunk/extensions/MobileFrontend/MobileFrontend.php  2012-03-06 22:56:08 UTC 
(rev 113193)
+++ trunk/extensions/MobileFrontend/MobileFrontend.php  2012-03-06 22:59:41 UTC 
(rev 113194)
@@ -49,6 +49,7 @@
        'MobileFormatter' => 'MobileFormatter',
        'WmlContext' => 'WmlContext',
 
+       'ApiMobileView' => 'api/ApiMobileView',
        'ApiParseExtender' => 'api/ApiParseExtender',
        'ApiQueryExcerpts' => 'api/ApiQueryExcerpts',
 
@@ -114,6 +115,7 @@
 $wgExtensionFunctions[] = 'efMobileFrontend_Setup';
 
 $wgAPIPropModules['excerpts'] = 'ApiQueryExcerpts';
+$wgAPIModules['mobileview'] = 'ApiMobileView';
 
 $wgHooks['APIGetAllowedParams'][] = 'ApiParseExtender::onAPIGetAllowedParams';
 $wgHooks['APIAfterExecute'][] = 'ApiParseExtender::onAPIAfterExecute';

Added: trunk/extensions/MobileFrontend/api/ApiMobileView.php
===================================================================
--- trunk/extensions/MobileFrontend/api/ApiMobileView.php                       
        (rev 0)
+++ trunk/extensions/MobileFrontend/api/ApiMobileView.php       2012-03-06 
22:59:41 UTC (rev 113194)
@@ -0,0 +1,167 @@
+<?php
+
+class ApiMobileView extends ApiBase {
+       /**
+        * Increment this when changing the format of cached data
+        */
+       const CACHE_VERSION = 1;
+
+       public function __construct( $main, $action ) {
+               parent::__construct( $main, $action );
+       }
+
+       public function execute() {
+               wfProfileIn( __METHOD__ );
+               // Enough '*' keys in JSON!!!
+               $textElement = $this->getMain()->getPrinter()->getFormat() == 
'XML' ? '*' : 'text';
+               $params = $this->extractRequestParams();
+               $requestedSections = isset( $params['section'] )
+                       ? $this->parseSections( $params['section'] )
+                       : array();
+               $prop = array_flip( $params['prop'] );
+               $sectionProp = $prop['sectionprop'];
+
+               $title = Title::newFromText( $params['page'] );
+               if ( !$title || !$title->exists() ) {
+                       $this->dieUsage( "Page `$page' does not exist", 
'nopage' );
+               }
+               if ( $title->getNamespace() < 0 || !$title->isLocal() ) {
+                       $this->dieUsage($description, $errorCode);
+               }
+               $data = $this->getData( $title, $params['noimages'] );
+               if ( isset( $prop['sections'] ) ) {
+                       $requestedSections = array_flip( $requestedSections );
+                       $result = $data['sections'];
+                       for ( $i = 0; $i < count( $data['sections'] ); $i++ ) {
+                               $result[$i]['id'] = $i;
+                               if ( isset( $requestedSections[$i] ) && isset( 
$data['text'][$i] ) ) {
+                                       $result[$i][$textElement] = 
$data['text'][$i];
+                               }
+                       }
+               } else {
+                       $result = array();
+                       foreach ( $requestedSections as $index ) {
+                               $section = array( 'id' => $index );
+                               if ( isset( $data['text'][$index] ) ) {
+                                       $section[$textElement] = 
$data['text'][$index];
+                               }
+                               $result[] = $section;
+                       }
+               }
+               $this->getResult()->setIndexedTagName( $result, 'section' );
+               $this->getResult()->addValue( null, $this->getModuleName(), 
array( 'sections' => $result ) );
+       }
+
+       public function getAllowedParams() {
+               return array(
+                       'page' => array(
+                               ApiBase::PARAM_REQUIRED => true,
+                       ),
+                       'section' => null,
+                       'prop' => array(
+                               ApiBase::PARAM_DFLT => 'text|sections',
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_TYPE => array(
+                                       'text',
+                                       'sections',
+                               )
+                       ),
+                       'sectionprop' => array(
+                               ApiBase::PARAM_TYPE => array(
+                                       'toclevel',
+                                       'level',
+                                       'line',
+                                       'number',
+                                       'index',
+                                       'fromtitle',
+                                       'anchor',
+                               ),
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_DFLT => 'toclevel|line',
+                       ),
+                       'noimages' => false,
+               );
+       }
+
+       private function parseSections( $str ) {
+               $sections = array_map( 'intval', explode( '|', $str ) );
+               return $sections;
+       }
+
+       private function getData( $title, $noImages ) {
+               global $wgMemc, $wgUseTidy;
+
+               wfProfileIn( __METHOD__ );
+               $wp = WikiPage::factory( $title );
+               $parserOptions = ParserOptions::newFromContext( $this );
+               $latest = $wp->getLatest();
+               $parserCacheKey = ParserCache::singleton()->getKey( $wp, 
$parserOptions );
+               $key = wfMemcKey( 'mf', 'mobileview', self::CACHE_VERSION, 
$noImages, $parserCacheKey );
+               $data = $wgMemc->get( $key );
+               if ( $data ) {
+                       wfProfileOut( __METHOD__ );
+                       return $data;
+               }
+               $parserOutput = $wp->getParserOutput( $parserOptions );
+               $mf = new MobileFormatter( '<html><body><div id="content">' . 
$parserOutput->getText() . '</div></body></html>',
+                       $title,
+                       'XHTML'
+               );
+               $mf->removeImages( $noImages );
+               $mf->filterContent();
+               $html = $mf->getText( 'content' );
+               $data = array();
+               $data['sections'] = $parserOutput->getSections();
+               $chunks = preg_split( '/<h(?=[1-6]\b)/i', $html );
+               $data['text'] = array();
+               foreach ( $chunks as $chunk ) {
+                       if ( count( $data['text'] ) ) {
+                               $chunk = "<h$chunk";
+                       }
+                       if ( $wgUseTidy && count( $chunks ) > 1 ) {
+                               $chunk = MWTidy::tidy( $chunk );
+                       }
+                       $data['text'][] = $chunk;
+               }
+               if ( count( $chunks ) != count( $data['sections'] ) + 1 ) {
+                       wfDebug( __METHOD__ . "(): mismatching number of 
sections from parser and split. oldid=$latest\n" );
+               }
+               // store for the same time as original parser output
+               $wgMemc->set( $key, $data, $parserOutput->getCacheTime() );
+               wfProfileOut( __METHOD__ );
+               return $data;
+       }
+
+       public function getParamDescription() {
+               return array(
+                       
+               );
+       }
+
+       public function getDescription() {
+               return 'Returns data needed for mobile views';
+       }
+
+       public function getPossibleErrors() {
+               return array_merge( parent::getPossibleErrors(),
+                       array(
+                               array( 'code' => 'invalid-section', 'info' => 
'' ),
+                       ) 
+               );
+       }
+
+       public function getExamples() {
+               return array(
+                       'api.php?action=mobileview&page=Doom_metal&section=0'
+               );
+       }
+
+       public function getHelpUrls() {
+               return 
'https://www.mediawiki.org/wiki/Extension:MobileFrontend#New_API';
+       }
+
+       public function getVersion() {
+               return __CLASS__ . ': $Id$';
+       }
+
+}


Property changes on: trunk/extensions/MobileFrontend/api/ApiMobileView.php
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to