python3 dgs/webserver.py -h
usage: webserver.py [-h] [--debug] [--port PORT] [--host HOST]
Diagrams rendering webservice
optional arguments:
-h, --help show this help message and exit
--debug run in debug mode
--port PORT the port to use
--host HOST the host to serve for
export PYTHONPATH="."
python3 dgs/webserver.py
By default the webservice will be available on port 5003.
You might want to adapt the url "https://diagrams.bitplan.com" to your webserver's url e.g. "http://localhost:5003"
curl -X POST -F 'generator=plantuml' -F source='version' https://diagrams.bitplan.com/render
should return
{
"diagrams": {
"png": {
"url": "https://diagrams.bitplan.com/render/png/0x97cd3329.png"
}
}
https://diagrams.bitplan.com/render/png/0x97cd3329.png containing:
The webservice can be used as endpoint for the the MediaWiki diagrams extension
Extension | |
---|---|
edit | |
name | Diagrams |
url | https://www.mediawiki.org/wiki/Extension:Diagrams |
purpose | Replaces deprecated
https://www.mediawiki.org/wiki/Extension:GraphViz and https://www.mediawiki.org/wiki/Extension:PlantUML extensions |
since | 2019/12/12 |
wiki |
git clone https://github.com/samwilson/diagrams-extension Diagrams
wfLoadExtension( 'Diagrams' );
// The URL at which you installed the Diagrams Service.
$wgDiagramsServiceUrl = 'http://diagrams.bitplan.com';
cd extensions
git clone https://github.com/samwilson/diagrams-extension.git Diagrams
Cloning into 'Diagrams'...
in LocalSettings.php add
$wgDiagramsServiceUrl ='https://diagrams.bitplan.com';
wfLoadExtension( 'Diagrams' );
replacing the $wgDiagramsServiceUrl with your own webservice to improve performance
cd extensions
git clone https://github.com/samwilson/diagrams-extension.git Diagrams
Cloning into 'Diagrams'...
in LocalSettings.php add
$wgDiagramsServiceUrl ='https://diagrams.bitplan.com';
wfLoadExtension( 'Diagrams' );
replacing the $wgDiagramsServiceUrl with your own webservice to improve performance
<?php
namespace MediaWiki\Extension\Diagrams;
use Html;
use Http;
use MediaWiki\MediaWikiServices;
use Parser;
use MediaWiki\Logger\LoggerFactory;
class Hooks {
/**
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ParserFirstCallInit
* @param Parser $parser
*/
public static function onParserFirstCallInit( Parser $parser ) {
foreach ( [ 'graphviz', 'mscgen', 'uml' ] as $tag ) {
$parser->setHook( $tag, function ( string $input, array $args) use ( $tag ) {
$logger = LoggerFactory::getInstance( 'Diagrams' );
$logger->debug("tag=".$tag);
$generator=$tag;
switch ($tag) {
case 'graphviz': $format='cmapx';break;
case 'mscgen' : $format='ismap';break;
case 'uml': $format='png';$generator='plantuml'; break;
default: $format="png";
}
if (isset($args["format"])) {
$format=$args["format"];
$logger->debug("log format=".$format);
}
// Make sure there's something to render.
$input = trim( $input );
if ( $input === '' ) {
return '';
}
return static::render( $generator, $input, $format );
} );
}
}
/**
* Get HTML for an error message.
* @param string $error Error message. May contain HTML.
* @return string
*/
protected static function formatError( $error ) {
return Html::rawElement( 'span', [ 'class' => 'ext-diagrams error' ], $error );
}
/**
* The main rendering method, handling all types.
* @param string $generator
* @param string $input
* @param string $format
* @return string
*/
protected static function render( $generator, $input, $format) {
$baseUrl = MediaWikiServices::getInstance()->getMainConfig()->get( 'DiagramsServiceUrl' );
$url = trim( $baseUrl, '/' ) . '/render';
# log debug information
$logger = LoggerFactory::getInstance( 'Diagrams' );
$logger->debug("url=".$url);
$logger->debug("generator=".$generator);
$logger->debug("format=".$format);
$params = [
'postData' => http_build_query( [
'generator' => $generator,
'types' => $format,
'source' => $input,
] ),
];
$result = Http::request( 'POST', $url, $params, __METHOD__ );
if ( $result === false ) {
return static::formatError( wfMessage( 'diagrams-error-no-response' ) );
}
$response = json_decode( $result );
if ( isset( $response->error ) ) {
$error = wfMessage( 'diagrams-error-returned-' . $response->error );
if ( isset( $response->message ) ) {
$error .= Html::element( 'br' ) . $response->message;
}
return static::formatError( $error );
}
if ( isset( $response->diagrams->cmapx->contents ) ) {
// Image maps in cmapx format.
$imageMap = new ImageMap( $response->diagrams->cmapx->contents );
if ( $imageMap->hasAreas() ) {
$imgAttrs['usemap'] = '#' . $imageMap->getName();
}
$out = Html::element( 'img', $imgAttrs );
if ( $imageMap->hasAreas() ) {
$out .= $imageMap->getMap();
}
} elseif ( isset( $response->diagrams->ismap->contents ) ) {
// Image maps in imap format.
$imgAttrs['ismap'] = true;
$out = Html::rawElement(
'a',
[ 'href' => $response->diagrams->ismap->url ],
Html::element( 'img', $imgAttrs )
);
} else {
// No image map. - plain format
switch ($format) {
case 'svg':
$objectAttrs= [ 'data' => $response->diagrams->svg->url, type=>'image/svg+xml'];
$out = Html::rawElement(
'object',
$objectAttrs
);
break;
default:
$imgAttrs = [ 'src' => $response->diagrams->png->url ];
$out = Html::element( 'img', $imgAttrs );
}
}
return Html::rawElement( 'div', [ 'class' => 'ext-diagrams' ], $out );
}
}
The communication between the MediaWiki diagrams extension and this webservice is done with POST requests that expect Json responses.
Example
{
"diagrams": {
"png": {
"url": "http://diagrams.bitplan.com/render/png/0xb00d69ad"
}
}
}
Example
{
"error": "service not ready",
"message": "not implemented yet"
}
Example
{
"diagrams": {
"png": {
"url": "http://diagrams.bitplan.com/render/png/0xb00d69ad"
}
}
}