Mw_parse: Add code for getUrl

pull/620/head
gnosygnu 8 years ago
parent 55f148480c
commit 909c96a1ff

@ -63,11 +63,18 @@ public class Gfo_url_encoder_ {
.Init__diff__one(Byte_ascii.Space, Byte_ascii.Plus); .Init__diff__one(Byte_ascii.Space, Byte_ascii.Plus);
} }
public static Gfo_url_encoder_mkr New__php_urlencode() { public static Gfo_url_encoder_mkr New__php_urlencode() {
// equivalent to php's urlencode; http://php.net/manual/en/function.urlencode.php; // REF: http://php.net/manual/en/function.urlencode.php;
// "Returns a String in which all non-alphanumeric characters except -_. have been replaced with a percent (%) sign followed by two hex digits and spaces encoded as plus (+) signs" // "Returns a String in which all non-alphanumeric characters except -_. have been replaced with a percent (%) sign followed by two hex digits and spaces encoded as plus (+) signs"
return new Gfo_url_encoder_mkr().Init(Byte_ascii.Percent).Init_common(Bool_.Y) return new Gfo_url_encoder_mkr().Init(Byte_ascii.Percent).Init_common(Bool_.Y)
.Init__diff__one(Byte_ascii.Space, Byte_ascii.Plus); .Init__diff__one(Byte_ascii.Space, Byte_ascii.Plus);
} }
public static Gfo_url_encoder_mkr New__php_rawurlencode() {
// REF: http://php.net/manual/en/function.rawurlencode.php
// "Returns a String in which all non-alphanumeric characters except -_.~ have been replaced with a percent (%) sign followed by two hex digits. "
return new Gfo_url_encoder_mkr().Init(Byte_ascii.Percent).Init_common(Bool_.Y)
.Init__same__many(Byte_ascii.Tilde)
.Init__diff__one(Byte_ascii.Space, Byte_ascii.Plus);
}
private static Gfo_url_encoder_mkr New__http_url_ttl() { private static Gfo_url_encoder_mkr New__http_url_ttl() {
return new Gfo_url_encoder_mkr().Init(Byte_ascii.Percent).Init_common(Bool_.Y); return new Gfo_url_encoder_mkr().Init(Byte_ascii.Percent).Init_common(Bool_.Y);
} }
@ -110,5 +117,6 @@ public class Gfo_url_encoder_ {
, Http_url_ttl = Gfo_url_encoder_.New__http_url_ttl().Make() , Http_url_ttl = Gfo_url_encoder_.New__http_url_ttl().Make()
, Mw_ttl = Gfo_url_encoder_.New__mw_ttl().Make() , Mw_ttl = Gfo_url_encoder_.New__mw_ttl().Make()
, Php_urlencode = Gfo_url_encoder_.New__php_urlencode().Make() , Php_urlencode = Gfo_url_encoder_.New__php_urlencode().Make()
, Php_rawurlencode = Gfo_url_encoder_.New__php_rawurlencode().Make()
; ;
} }

@ -15,19 +15,9 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package gplx.xowa.mws.filerepos.files; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; import gplx.xowa.mws.filerepos.*; package gplx.langs.phps.utls; import gplx.*; import gplx.langs.*; import gplx.langs.phps.*;
public class Xomw_file { public class Php_encode_ {
public byte[] url; public static byte[] rawurlencode(byte[] v) {
public boolean Allow_inline_display() { return gplx.langs.htmls.encoders.Gfo_url_encoder_.Php_rawurlencode.Encode(v);
return true;
}
public boolean Is_vectorized() {
return false;
}
public int Get_width(int page) {
return -1;
}
public boolean Must_render() {
return true;
} }
} }

@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.langs.phps.utls; import gplx.*; import gplx.langs.*; import gplx.langs.phps.*; package gplx.langs.phps.utls; import gplx.*; import gplx.langs.*; import gplx.langs.phps.*;
import gplx.core.btries.*; import gplx.core.btries.*;
public class Php_str_ { public class Php_str_ {
public static int Strpos(byte[] src, byte find) {return Strpos(src, find, 0, src.length);}
public static int Strpos(byte[] src, byte find, int bgn, int end) { public static int Strpos(byte[] src, byte find, int bgn, int end) {
return Bry_find_.Find_fwd(src, find, bgn, end); return Bry_find_.Find_fwd(src, find, bgn, end);
} }

@ -32,7 +32,7 @@ public class Xoa_app_ {
} }
} }
public static final String Name = "xowa"; public static final String Name = "xowa";
public static final int Version_id = 513; public static final int Version_id = 514;
public static final String Version = "4.1.0.1702"; // RELEASE:2017-01-03 20:30 public static final String Version = "4.1.0.1702"; // RELEASE:2017-01-03 20:30
public static String Build_date = "2012-12-30 00:00:00"; public static String Build_date = "2012-12-30 00:00:00";
public static String Build_date_fmt = "yyyy-MM-dd HH:mm:ss"; public static String Build_date_fmt = "yyyy-MM-dd HH:mm:ss";

@ -19,7 +19,7 @@ package gplx.xowa.mws; import gplx.*; import gplx.xowa.*;
import gplx.core.btries.*; import gplx.core.btries.*;
import gplx.langs.htmls.*; import gplx.langs.htmls.*;
import gplx.xowa.mws.htmls.*; import gplx.xowa.mws.linkers.*; import gplx.xowa.mws.parsers.*; import gplx.xowa.mws.htmls.*; import gplx.xowa.mws.linkers.*; import gplx.xowa.mws.parsers.*;
import gplx.xowa.mws.filerepos.files.*; import gplx.xowa.mws.medias.*; import gplx.xowa.mws.filerepo.file.*; import gplx.xowa.mws.media.*;
import gplx.langs.phps.utls.*; import gplx.langs.phps.utls.*;
/* TODO.XO /* TODO.XO
* P8: wfMessage * P8: wfMessage
@ -90,10 +90,10 @@ public class Xomw_linker {
// @param int|null width_option Used by the parser to remember the user preference thumbnailsize // @param int|null width_option Used by the parser to remember the user preference thumbnailsize
// @since 1.20 // @since 1.20
// @return String HTML for an image, with links, wrappers, etc. // @return String HTML for an image, with links, wrappers, etc.
public void Make_image_link(Bry_bfr bfr, Xomw_parser parser, Xoa_ttl title, Xomw_file file, Xomw_img_prms frame_params, Xomw_mda_prms handler_params, Object time, byte[] query, Object widthOption) { public void Make_image_link(Bry_bfr bfr, Xomw_parser parser, Xoa_ttl title, Xomw_File file, Xomw_img_prms frame_params, Xomw_mda_prms handler_params, Object time, byte[] query, Object widthOption) {
// XO.MW.HOOK:ImageBeforeProduceHTML // XO.MW.HOOK:ImageBeforeProduceHTML
if (file != null && !file.Allow_inline_display()) { if (file != null && !file.allowInlineDisplay()) {
// this.Link(bfr, title, Bry_.Empty, tmp_attribs, tmp_query, tmp_options); // this.Link(bfr, title, Bry_.Empty, tmp_attribs, tmp_query, tmp_options);
return; return;
} }
@ -121,14 +121,14 @@ public class Xomw_linker {
frame_params.align = Align__frame__none; frame_params.align = Align__frame__none;
} }
if (file != null && handler_params.width == -1) { if (file != null && handler_params.width == -1) {
if (handler_params.height != -1 && file.Is_vectorized()) { if (handler_params.height != -1 && file.isVectorized()) {
// If its a vector image, and user only specifies height // If its a vector image, and user only specifies height
// we don't want it to be limited by its "normal" width. // we don't want it to be limited by its "normal" width.
// global $wgSVGMaxSize; // global $wgSVGMaxSize;
// handler_params.width = $wgSVGMaxSize; // handler_params.width = $wgSVGMaxSize;
} }
else { else {
handler_params.width = file.Get_width(page); handler_params.width = file.getWidth(page);
} }
if ( frame_params.thumbnail != null if ( frame_params.thumbnail != null
@ -159,7 +159,7 @@ public class Xomw_linker {
// Use width which is smaller: real image width or user preference width // Use width which is smaller: real image width or user preference width
// Unless image is scalable vector. // Unless image is scalable vector.
if (handler_params.height == -1 && handler_params.width <= 0 || if (handler_params.height == -1 && handler_params.width <= 0 ||
pref_width < handler_params.width || file.Is_vectorized()) { pref_width < handler_params.width || file.isVectorized()) {
handler_params.width = pref_width; handler_params.width = pref_width;
} }
} }
@ -182,19 +182,20 @@ public class Xomw_linker {
} }
if (file != null && frame_params.frameless != null) { if (file != null && frame_params.frameless != null) {
int src_width = file.Get_width(page); int src_width = file.getWidth(page);
// For "frameless" option: do not present an image bigger than the // For "frameless" option: do not present an image bigger than the
// source (for bitmap-style images). This is the same behavior as the // source (for bitmap-style images). This is the same behavior as the
// "thumb" option does it already. // "thumb" option does it already.
if (src_width != -1 && !file.Must_render() && handler_params.width > src_width) { if (src_width != -1 && !file.mustRender() && handler_params.width > src_width) {
handler_params.width = src_width; handler_params.width = src_width;
} }
} }
Xomw_mto thumb = new Xomw_mto(file.url); Xomw_mto thumb = null;
if (file != null && handler_params.width != -1) { if (file != null && handler_params.width != -1) {
// Create a resized image, without the additional thumbnail features // Create a resized image, without the additional thumbnail features
// $thumb = $file->transform(handler_params); // $thumb = $file->transform(handler_params);
thumb = new Xomw_mto(file.getUrl());
} }
else { else {
thumb = null; thumb = null;
@ -203,6 +204,7 @@ public class Xomw_linker {
byte[] s = null; byte[] s = null;
if (thumb == null) { if (thumb == null) {
// $s = self::makeBrokenImageLinkObj($title, frame_params['title'], '', '', '', $time == true); // $s = self::makeBrokenImageLinkObj($title, frame_params['title'], '', '', '', $time == true);
s = Bry_.Empty;
} }
else { else {
// self::processResponsiveImages($file, $thumb, handler_params); // self::processResponsiveImages($file, $thumb, handler_params);
@ -267,7 +269,7 @@ public class Xomw_linker {
} }
} }
public void Make_thumb_link2(Bry_bfr bfr, Xoa_ttl title, Xomw_file file, Xomw_img_prms frame_params, Xomw_mda_prms handler_params, Object time, byte[] query) { public void Make_thumb_link2(Bry_bfr bfr, Xoa_ttl title, Xomw_File file, Xomw_img_prms frame_params, Xomw_mda_prms handler_params, Object time, byte[] query) {
boolean exists = false; // = $file && $file->exists(); boolean exists = false; // = $file && $file->exists();
int page = handler_params.page; int page = handler_params.page;
@ -313,14 +315,14 @@ public class Xomw_linker {
else if (frame_params.framed != null) { else if (frame_params.framed != null) {
// Use image dimensions, don't scale // Use image dimensions, don't scale
// thumb = $file->getUnscaledThumb(handler_params); // thumb = $file->getUnscaledThumb(handler_params);
thumb = new Xomw_mto(file.url); thumb = new Xomw_mto(file.getUrl());
no_scale = true; no_scale = true;
} }
else { else {
// Do not present an image bigger than the source, for bitmap-style images // Do not present an image bigger than the source, for bitmap-style images
// This is a hack to maintain compatibility with arbitrary pre-1.10 behavior // This is a hack to maintain compatibility with arbitrary pre-1.10 behavior
int src_width = file.Get_width(page); int src_width = file.getWidth(page);
if (src_width != -1 && !file.Must_render() && handler_params.width > src_width) { if (src_width != -1 && !file.mustRender() && handler_params.width > src_width) {
handler_params.width = src_width; handler_params.width = src_width;
} }
// thumb = $file->transform(handler_params); // thumb = $file->transform(handler_params);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,21 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.filerepo.file; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; import gplx.xowa.mws.filerepo.*;
public interface Xomw_file_finder {
Xomw_File Find_file(Xoa_ttl ttl);
}

@ -0,0 +1,28 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.filerepo.file; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; import gplx.xowa.mws.filerepo.*;
public class Xomw_file_finder__mock implements Xomw_file_finder {
private final Hash_adp hash = Hash_adp_.New();
public Xomw_File Find_file(Xoa_ttl ttl) {
return (Xomw_File)hash.Get_by(ttl.Page_db_as_str());
}
public void Add(String title, Xomw_FileRepo repo, int w, int h) {
Xomw_LocalFile file = new Xomw_LocalFile(Bry_.new_u8(title), repo, w, h);
hash.Add(title, file);
}
}

@ -0,0 +1,21 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.filerepo.file; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; import gplx.xowa.mws.filerepo.*;
public class Xomw_file_finder__noop implements Xomw_file_finder {
public Xomw_File Find_file(Xoa_ttl ttl) {return null;}
}

@ -0,0 +1,278 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
import gplx.xowa.mws.filerepo.file.*;
public class Xomw_ImageHandler extends Xomw_MediaHandler { /**
* @param File file
* @return boolean
*/
@Override public boolean canRender(Xomw_File file) {
return (file.getWidth(1) != -1 && file.getHeight(1) != -1);
}
// public function getParamMap() {
// return [ 'img_width' => 'width' ];
// }
//
// public function validateParam(name, value) {
// if (in_array(name, [ 'width', 'height' ])) {
// if (value <= 0) {
// return false;
// } else {
// return true;
// }
// } else {
// return false;
// }
// }
//
// public function makeParamString(params) {
// if (isset(params['physicalWidth'])) {
// width = params['physicalWidth'];
// } elseif (isset(params['width'])) {
// width = params['width'];
// } else {
// throw new MediaTransformInvalidParametersException('No width specified to ' . __METHOD__);
// }
//
// # Removed for ProofreadPage
// # width = intval(width);
// return "{width}px";
// }
//
// public function parseParamString(str) {
// m = false;
// if (preg_match('/^(\d+)px/', str, m)) {
// return [ 'width' => m[1] ];
// } else {
// return false;
// }
// }
//
// function getScriptParams(params) {
// return [ 'width' => params['width'] ];
// }
//
// /**
// * @param File image
// * @param array params
// * @return boolean
// */
// function normaliseParams(image, &params) {
// mimeType = image.getMimeType();
//
// if (!isset(params['width'])) {
// return false;
// }
//
// if (!isset(params['page'])) {
// params['page'] = 1;
// } else {
// params['page'] = intval(params['page']);
// if (params['page'] > image.pageCount()) {
// params['page'] = image.pageCount();
// }
//
// if (params['page'] < 1) {
// params['page'] = 1;
// }
// }
//
// srcWidth = image.getWidth(params['page']);
// srcHeight = image.getHeight(params['page']);
//
// if (isset(params['height']) && params['height'] != -1) {
// # Height & width were both set
// if (params['width'] * srcHeight > params['height'] * srcWidth) {
// # Height is the relative smaller dimension, so scale width accordingly
// params['width'] = self::fitBoxWidth(srcWidth, srcHeight, params['height']);
//
// if (params['width'] == 0) {
// # Very small image, so we need to rely on client side scaling :(
// params['width'] = 1;
// }
//
// params['physicalWidth'] = params['width'];
// } else {
// # Height was crap, unset it so that it will be calculated later
// unset(params['height']);
// }
// }
//
// if (!isset(params['physicalWidth'])) {
// # Passed all validations, so set the physicalWidth
// params['physicalWidth'] = params['width'];
// }
//
// # Because thumbs are only referred to by width, the height always needs
// # to be scaled by the width to keep the thumbnail sizes consistent,
// # even if it was set inside the if block above
// params['physicalHeight'] = File::scaleHeight(srcWidth, srcHeight,
// params['physicalWidth']);
//
// # Set the height if it was not validated in the if block higher up
// if (!isset(params['height']) || params['height'] == -1) {
// params['height'] = params['physicalHeight'];
// }
//
// if (!this.validateThumbParams(params['physicalWidth'],
// params['physicalHeight'], srcWidth, srcHeight, mimeType)
// ) {
// return false;
// }
//
// return true;
// }
//
// /**
// * Validate thumbnail parameters and fill in the correct height
// *
// * @param int width Specified width (input/output)
// * @param int height Height (output only)
// * @param int srcWidth Width of the source image
// * @param int srcHeight Height of the source image
// * @param String mimeType Unused
// * @return boolean False to indicate that an error should be returned to the user.
// */
// function validateThumbParams(&width, &height, srcWidth, srcHeight, mimeType) {
// width = intval(width);
//
// # Sanity check width
// if (width <= 0) {
// wfDebug(__METHOD__ . ": Invalid destination width: width\n");
//
// return false;
// }
// if (srcWidth <= 0) {
// wfDebug(__METHOD__ . ": Invalid source width: srcWidth\n");
//
// return false;
// }
//
// height = File::scaleHeight(srcWidth, srcHeight, width);
// if (height == 0) {
// # Force height to be at least 1 pixel
// height = 1;
// }
//
// return true;
// }
//
// /**
// * @param File image
// * @param String script
// * @param array params
// * @return boolean|MediaTransformOutput
// */
// function getScriptedTransform(image, script, params) {
// if (!this.normaliseParams(image, params)) {
// return false;
// }
// url = wfAppendQuery(script, this.getScriptParams(params));
//
// if (image.mustRender() || params['width'] < image.getWidth()) {
// return new ThumbnailImage(image, url, false, params);
// }
// }
//
// function getImageSize(image, path) {
// MediaWiki\suppressWarnings();
// gis = getimagesize(path);
// MediaWiki\restoreWarnings();
//
// return gis;
// }
//
// /**
// * Function that returns the number of pixels to be thumbnailed.
// * Intended for animated GIFs to multiply by the number of frames.
// *
// * If the file doesn't support a notion of "area" return 0.
// *
// * @param File image
// * @return int
// */
// function getImageArea(image) {
// return image.getWidth() * image.getHeight();
// }
//
// /**
// * @param File file
// * @return String
// */
// function getShortDesc(file) {
// global wgLang;
// nbytes = htmlspecialchars(wgLang.formatSize(file.getSize()));
// widthheight = wfMessage('widthheight')
// .numParams(file.getWidth(), file.getHeight()).escaped();
//
// return "widthheight (nbytes)";
// }
//
// /**
// * @param File file
// * @return String
// */
// function getLongDesc(file) {
// global wgLang;
// pages = file.pageCount();
// size = htmlspecialchars(wgLang.formatSize(file.getSize()));
// if (pages === false || pages <= 1) {
// msg = wfMessage('file-info-size').numParams(file.getWidth(),
// file.getHeight()).params(size,
// '<span class="mime-type">' . file.getMimeType() . '</span>').parse();
// } else {
// msg = wfMessage('file-info-size-pages').numParams(file.getWidth(),
// file.getHeight()).params(size,
// '<span class="mime-type">' . file.getMimeType() . '</span>').numParams(pages).parse();
// }
//
// return msg;
// }
//
// /**
// * @param File file
// * @return String
// */
// function getDimensionsString(file) {
// pages = file.pageCount();
// if (pages > 1) {
// return wfMessage('widthheightpage')
// .numParams(file.getWidth(), file.getHeight(), pages).text();
// } else {
// return wfMessage('widthheight')
// .numParams(file.getWidth(), file.getHeight()).text();
// }
// }
//
// public function sanitizeParamsForBucketing(params) {
// params = parent::sanitizeParamsForBucketing(params);
//
// // We unset the height parameters in order to let normaliseParams recalculate them
// // Otherwise there might be a height discrepancy
// if (isset(params['height'])) {
// unset(params['height']);
// }
//
// if (isset(params['physicalHeight'])) {
// unset(params['physicalHeight']);
// }
//
// return params;
// }
}

@ -0,0 +1,861 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
import gplx.xowa.mws.filerepo.file.*;
public class Xomw_MediaHandler {
// static final TRANSFORM_LATER = 1;
// static final METADATA_GOOD = true;
// static final METADATA_BAD = false;
// static final METADATA_COMPATIBLE = 2; // for old but backwards compatible.
// /**
// * Max length of error logged by logErrorForExternalProcess()
// */
// static final MAX_ERR_LOG_SIZE = 65535;
//
// /**
// * Get a MediaHandler for a given MIME type from the instance cache
// *
// * @param String $type
// * @return MediaHandler|boolean
// */
// static function getHandler($type) {
// return MediaWikiServices::getInstance()
// ->getMediaHandlerFactory()->getHandler($type);
// }
//
// /**
// * Get an associative array mapping magic word IDs to parameter names.
// * Will be used by the parser to identify parameters.
// */
// abstract public function getParamMap();
//
// /**
// * Validate a thumbnail parameter at parse time.
// * Return true to accept the parameter, and false to reject it.
// * If you return false, the parser will do something quiet and forgiving.
// *
// * @param String $name
// * @param mixed $value
// */
// abstract public function validateParam($name, $value);
//
// /**
// * Merge a parameter array into a String appropriate for inclusion in filenames
// *
// * @param array $params Array of parameters that have been through normaliseParams.
// * @return String
// */
// abstract public function makeParamString($params);
//
// /**
// * Parse a param String made with makeParamString back into an array
// *
// * @param String $str The parameter String without file name (e.g. 122px)
// * @return array|boolean Array of parameters or false on failure.
// */
// abstract public function parseParamString($str);
//
// /**
// * Changes the parameter array as necessary, ready for transformation.
// * Should be idempotent.
// * Returns false if the parameters are unacceptable and the transform should fail
// * @param File $image
// * @param array $params
// */
// abstract function normaliseParams($image, &$params);
//
// /**
// * Get an image size array like that returned by getimagesize(), or false if it
// * can't be determined.
// *
// * This function is used for determining the width, height and bitdepth directly
// * from an image. The results are stored in the database in the img_width,
// * img_height, img_bits fields.
// *
// * @note If this is a multipage file, return the width and height of the
// * first page.
// *
// * @param File|FSFile $image The image Object, or false if there isn't one.
// * Warning, FSFile::getPropsFromPath might pass an FSFile instead of File (!)
// * @param String $path The filename
// * @return array|boolean Follow the format of PHP getimagesize() @gplx.Internal protected function.
// * See https://secure.php.net/getimagesize. MediaWiki will only ever use the
// * first two array keys (the width and height), and the 'bits' associative
// * key. All other array keys are ignored. Returning a 'bits' key is optional
// * as not all formats have a notion of "bitdepth". Returns false on failure.
// */
// abstract function getImageSize($image, $path);
//
// /**
// * Get handler-specific metadata which will be saved in the img_metadata field.
// *
// * @param File|FSFile $image The image Object, or false if there isn't one.
// * Warning, FSFile::getPropsFromPath might pass an FSFile instead of File (!)
// * @param String $path The filename
// * @return String A String of metadata in php serialized form (Run through serialize())
// */
// function getMetadata($image, $path) {
// return '';
// }
//
// /**
// * Get metadata version.
// *
// * This is not used for validating metadata, this is used for the api when returning
// * metadata, since api content formats should stay the same over time, and so things
// * using ForeignApiRepo can keep backwards compatibility
// *
// * All core media handlers share a common version number, and extensions can
// * use the GetMetadataVersion hook to append to the array (they should append a unique
// * String so not to get confusing). If there was a media handler named 'foo' with metadata
// * version 3 it might add to the end of the array the element 'foo=3'. if the core metadata
// * version is 2, the end version String would look like '2;foo=3'.
// *
// * @return String Version String
// */
// static function getMetadataVersion() {
// $version = [ '2' ]; // core metadata version
// Hooks::run('GetMetadataVersion', [ &$version ]);
//
// return implode(';', $version);
// }
//
// /**
// * Convert metadata version.
// *
// * By default just returns $metadata, but can be used to allow
// * media handlers to convert between metadata versions.
// *
// * @param String|array $metadata Metadata array (serialized if String)
// * @param int $version Target version
// * @return array Serialized metadata in specified version, or $metadata on fail.
// */
// function convertMetadataVersion($metadata, $version = 1) {
// if (!is_array($metadata)) {
//
// // unserialize to keep return parameter consistent.
// MediaWiki\suppressWarnings();
// $ret = unserialize($metadata);
// MediaWiki\restoreWarnings();
//
// return $ret;
// }
//
// return $metadata;
// }
//
// /**
// * Get a String describing the type of metadata, for display purposes.
// *
// * @note This method is currently unused.
// * @param File $image
// * @return String
// */
// function getMetadataType($image) {
// return false;
// }
//
// /**
// * Check if the metadata String is valid for this handler.
// * If it returns MediaHandler::METADATA_BAD (or false), Image
// * will reload the metadata from the file and update the database.
// * MediaHandler::METADATA_GOOD for if the metadata is a-ok,
// * MediaHandler::METADATA_COMPATIBLE if metadata is old but backwards
// * compatible (which may or may not trigger a metadata reload).
// *
// * @note Returning self::METADATA_BAD will trigger a metadata reload from
// * file on page view. Always returning this from a broken file, or suddenly
// * triggering as bad metadata for a large number of files can cause
// * performance problems.
// * @param File $image
// * @param String $metadata The metadata in serialized form
// * @return boolean
// */
// function isMetadataValid($image, $metadata) {
// return self::METADATA_GOOD;
// }
//
// /**
// * Get an array of standard (FormatMetadata type) metadata values.
// *
// * The returned data is largely the same as that from getMetadata(),
// * but formatted in a standard, stable, handler-independent way.
// * The idea being that some values like ImageDescription or Artist
// * are universal and should be retrievable in a handler generic way.
// *
// * The specific properties are the type of properties that can be
// * handled by the FormatMetadata class. These values are exposed to the
// * user via the filemetadata parser function.
// *
// * Details of the response format of this function can be found at
// * https://www.mediawiki.org/wiki/Manual:File_metadata_handling
// * tl/dr: the response is an associative array of
// * properties keyed by name, but the value can be complex. You probably
// * want to call one of the FormatMetadata::flatten* functions on the
// * property values before using them, or call
// * FormatMetadata::getFormattedData() on the full response array, which
// * transforms all values into prettified, human-readable text.
// *
// * Subclasses overriding this function must return a value which is a
// * valid API response fragment (all associative array keys are valid
// * XML tagnames).
// *
// * Note, if the file simply has no metadata, but the handler supports
// * this interface, it should return an empty array, not false.
// *
// * @param File $file
// * @return array|boolean False if interface not supported
// * @since 1.23
// */
// public function getCommonMetaArray(File $file) {
// return false;
// }
//
// /**
// * Get a MediaTransformOutput Object representing an alternate of the transformed
// * output which will call an intermediary thumbnail assist script.
// *
// * Used when the repository has a thumbnailScriptUrl option configured.
// *
// * Return false to fall back to the regular getTransform().
// * @param File $image
// * @param String $script
// * @param array $params
// * @return boolean|ThumbnailImage
// */
// function getScriptedTransform($image, $script, $params) {
// return false;
// }
//
// /**
// * Get a MediaTransformOutput Object representing the transformed output. Does not
// * actually do the transform.
// *
// * @param File $image The image Object
// * @param String $dstPath Filesystem destination path
// * @param String $dstUrl Destination URL to use in output HTML
// * @param array $params Arbitrary set of parameters validated by $this->validateParam()
// * @return MediaTransformOutput
// */
// final function getTransform($image, $dstPath, $dstUrl, $params) {
// return $this->doTransform($image, $dstPath, $dstUrl, $params, self::TRANSFORM_LATER);
// }
//
// /**
// * Get a MediaTransformOutput Object representing the transformed output. Does the
// * transform unless $flags contains self::TRANSFORM_LATER.
// *
// * @param File $image The image Object
// * @param String $dstPath Filesystem destination path
// * @param String $dstUrl Destination URL to use in output HTML
// * @param array $params Arbitrary set of parameters validated by $this->validateParam()
// * Note: These parameters have *not* gone through $this->normaliseParams()
// * @param int $flags A bitfield, may contain self::TRANSFORM_LATER
// * @return MediaTransformOutput
// */
// abstract function doTransform($image, $dstPath, $dstUrl, $params, $flags = 0);
//
// /**
// * Get the thumbnail extension and MIME type for a given source MIME type
// *
// * @param String $ext Extension of original file
// * @param String $mime MIME type of original file
// * @param array $params Handler specific rendering parameters
// * @return array Thumbnail extension and MIME type
// */
// function getThumbType($ext, $mime, $params = null) {
// $magic = MimeMagic::singleton();
// if (!$ext || $magic->isMatchingExtension($ext, $mime) === false) {
// // The extension is not valid for this MIME type and we do
// // recognize the MIME type
// $extensions = $magic->getExtensionsForType($mime);
// if ($extensions) {
// return [ strtok($extensions, ' '), $mime ];
// }
// }
//
// // The extension is correct (true) or the MIME type is unknown to
// // MediaWiki (null)
// return [ $ext, $mime ];
// }
//
// /**
// * Get useful response headers for GET/HEAD requests for a file with the given metadata
// *
// * @param mixed $metadata Result of the getMetadata() function of this handler for a file
// * @return array
// */
// public function getStreamHeaders($metadata) {
// return [];
// }
/**
* True if the handled types can be transformed
*
* @param File $file
* @return boolean
*/
@gplx.Virtual public boolean canRender(Xomw_File file) {
return true;
}
//
// /**
// * True if handled types cannot be displayed directly in a browser
// * but can be rendered
// *
// * @param File $file
// * @return boolean
// */
// public function mustRender($file) {
// return false;
// }
//
// /**
// * True if the type has multi-page capabilities
// *
// * @param File $file
// * @return boolean
// */
// public function isMultiPage($file) {
// return false;
// }
//
// /**
// * Page count for a multi-page document, false if unsupported or unknown
// *
// * @param File $file
// * @return boolean
// */
// function pageCount(File $file) {
// return false;
// }
//
// /**
// * The material is vectorized and thus scaling is lossless
// *
// * @param File $file
// * @return boolean
// */
// function isVectorized($file) {
// return false;
// }
//
// /**
// * The material is an image, and is animated.
// * In particular, video material need not return true.
// * @note Before 1.20, this was a method of ImageHandler only
// *
// * @param File $file
// * @return boolean
// */
// function isAnimatedImage($file) {
// return false;
// }
//
// /**
// * If the material is animated, we can animate the thumbnail
// * @since 1.20
// *
// * @param File $file
// * @return boolean If material is not animated, handler may return any value.
// */
// function canAnimateThumbnail($file) {
// return true;
// }
//
// /**
// * False if the handler is disabled for all files
// * @return boolean
// */
// function isEnabled() {
// return true;
// }
//
// /**
// * Get an associative array of page dimensions
// * Currently "width" and "height" are understood, but this might be
// * expanded in the future.
// * Returns false if unknown.
// *
// * It is expected that handlers for paged media (e.g. DjVuHandler)
// * will override this method so that it gives the correct results
// * for each specific page of the file, using the $page argument.
// *
// * @note For non-paged media, use getImageSize.
// *
// * @param File $image
// * @param int $page What page to get dimensions of
// * @return array|boolean
// */
// function getPageDimensions(File $image, $page) {
// $gis = $this->getImageSize($image, $image->getLocalRefPath());
// if ($gis) {
// return [
// 'width' => $gis[0],
// 'height' => $gis[1]
// ];
// } else {
// return false;
// }
// }
//
// /**
// * Generic getter for text layer.
// * Currently overloaded by PDF and DjVu handlers
// * @param File $image
// * @param int $page Page number to get information for
// * @return boolean|String Page text or false when no text found or if
// * unsupported.
// */
// function getPageText(File $image, $page) {
// return false;
// }
//
// /**
// * Get the text of the entire document.
// * @param File $file
// * @return boolean|String The text of the document or false if unsupported.
// */
// public function getEntireText(File $file) {
// $numPages = $file->pageCount();
// if (!$numPages) {
// // Not a multipage document
// return $this->getPageText($file, 1);
// }
// $document = '';
// for ($i = 1; $i <= $numPages; $i++) {
// $curPage = $this->getPageText($file, $i);
// if (is_string($curPage)) {
// $document .= $curPage . "\n";
// }
// }
// if ($document !== '') {
// return $document;
// }
// return false;
// }
//
// /**
// * Get an array structure that looks like this:
// *
// * [
// * 'visible' => [
// * 'Human-readable name' => 'Human readable value',
// * ...
// * ],
// * 'collapsed' => [
// * 'Human-readable name' => 'Human readable value',
// * ...
// * ]
// * ]
// * The UI will format this into a table where the visible fields are always
// * visible, and the collapsed fields are optionally visible.
// *
// * The function should return false if there is no metadata to display.
// */
//
// /**
// * @todo FIXME: This interface is not very flexible. The media handler
// * should generate HTML instead. It can do all the formatting according
// * to some standard. That makes it possible to do things like visual
// * indication of grouped and chained streams in ogg container files.
// * @param File $image
// * @param boolean|IContextSource $context Context to use (optional)
// * @return array|boolean
// */
// function formatMetadata($image, $context = false) {
// return false;
// }
//
// /** sorts the visible/invisible field.
// * Split off from ImageHandler::formatMetadata, as used by more than
// * one type of handler.
// *
// * This is used by the media handlers that use the FormatMetadata class
// *
// * @param array $metadataArray Metadata array
// * @param boolean|IContextSource $context Context to use (optional)
// * @return array Array for use displaying metadata.
// */
// function formatMetadataHelper($metadataArray, $context = false) {
// $result = [
// 'visible' => [],
// 'collapsed' => []
// ];
//
// $formatted = FormatMetadata::getFormattedData($metadataArray, $context);
// // Sort fields into visible and collapsed
// $visibleFields = $this->visibleMetadataFields();
// foreach ($formatted as $name => $value) {
// $tag = strtolower($name);
// self::addMeta($result,
// in_array($tag, $visibleFields) ? 'visible' : 'collapsed',
// 'exif',
// $tag,
// $value
// );
// }
//
// return $result;
// }
//
// /**
// * Get a list of metadata items which should be displayed when
// * the metadata table is collapsed.
// *
// * @return array Array of strings
// */
// protected function visibleMetadataFields() {
// return FormatMetadata::getVisibleFields();
// }
//
// /**
// * This is used to generate an array element for each metadata value
// * That array is then used to generate the table of metadata values
// * on the image page
// *
// * @param array &$array An array containing elements for each type of visibility
// * and each of those elements being an array of metadata items. This function adds
// * a value to that array.
// * @param String $visibility ('visible' or 'collapsed') if this value is hidden
// * by default.
// * @param String $type Type of metadata tag (currently always 'exif')
// * @param String $id The name of the metadata tag (like 'artist' for example).
// * its name in the table displayed is the message "$type-$id" (Ex exif-artist).
// * @param String $value Thingy goes into a wikitext table; it used to be escaped but
// * that was incompatible with previous practise of customized display
// * with wikitext formatting via messages such as 'exif-model-value'.
// * So the escaping is taken back out, but generally this seems a confusing
// * interface.
// * @param boolean|String $param Value to pass to the message for the name of the field
// * as $1. Currently this parameter doesn't seem to ever be used.
// *
// * Note, everything here is passed through the parser later on (!)
// */
// protected static function addMeta(&$array, $visibility, $type, $id, $value, $param = false) {
// $msg = wfMessage("$type-$id", $param);
// if ($msg->exists()) {
// $name = $msg->text();
// } else {
// // This is for future compatibility when using instant commons.
// // So as to not display as ugly a name if a new metadata
// // property is defined that we don't know about
// // (not a major issue since such a property would be collapsed
// // by default).
// wfDebug(__METHOD__ . ' Unknown metadata name: ' . $id . "\n");
// $name = wfEscapeWikiText($id);
// }
// $array[$visibility][] = [
// 'id' => "$type-$id",
// 'name' => $name,
// 'value' => $value
// ];
// }
//
// /**
// * Short description. Shown on Special:Search results.
// *
// * @param File $file
// * @return String
// */
// function getShortDesc($file) {
// return self::getGeneralShortDesc($file);
// }
//
// /**
// * Long description. Shown under image on image description page surounded by ().
// *
// * @param File $file
// * @return String
// */
// function getLongDesc($file) {
// return self::getGeneralLongDesc($file);
// }
//
// /**
// * Used instead of getShortDesc if there is no handler registered for file.
// *
// * @param File $file
// * @return String
// */
// static function getGeneralShortDesc($file) {
// global $wgLang;
//
// return htmlspecialchars($wgLang->formatSize($file->getSize()));
// }
//
// /**
// * Used instead of getLongDesc if there is no handler registered for file.
// *
// * @param File $file
// * @return String
// */
// static function getGeneralLongDesc($file) {
// return wfMessage('file-info')->sizeParams($file->getSize())
// ->params('<span class="mime-type">' . $file->getMimeType() . '</span>')->parse();
// }
//
// /**
// * Calculate the largest thumbnail width for a given original file size
// * such that the thumbnail's height is at most $maxHeight.
// * @param int $boxWidth Width of the thumbnail box.
// * @param int $boxHeight Height of the thumbnail box.
// * @param int $maxHeight Maximum height expected for the thumbnail.
// * @return int
// */
// public static function fitBoxWidth($boxWidth, $boxHeight, $maxHeight) {
// $idealWidth = $boxWidth * $maxHeight / $boxHeight;
// $roundedUp = ceil($idealWidth);
// if (round($roundedUp * $boxHeight / $boxWidth) > $maxHeight) {
// return floor($idealWidth);
// } else {
// return $roundedUp;
// }
// }
//
// /**
// * Shown in file history box on image description page.
// *
// * @param File $file
// * @return String Dimensions
// */
// function getDimensionsString($file) {
// return '';
// }
//
// /**
// * Modify the parser Object post-transform.
// *
// * This is often used to do $parser->addOutputHook(),
// * in order to add some javascript to render a viewer.
// * See TimedMediaHandler or OggHandler for an example.
// *
// * @param Parser $parser
// * @param File $file
// */
// function parserTransformHook($parser, $file) {
// }
//
// /**
// * File validation hook called on upload.
// *
// * If the file at the given local path is not valid, or its MIME type does not
// * match the handler class, a Status Object should be returned containing
// * relevant errors.
// *
// * @param String $fileName The local path to the file.
// * @return Status
// */
// function verifyUpload($fileName) {
// return Status::newGood();
// }
//
// /**
// * Check for zero-sized thumbnails. These can be generated when
// * no disk space is available or some other error occurs
// *
// * @param String $dstPath The location of the suspect file
// * @param int $retval Return value of some shell process, file will be deleted if this is non-zero
// * @return boolean True if removed, false otherwise
// */
// function removeBadFile($dstPath, $retval = 0) {
// if (file_exists($dstPath)) {
// $thumbstat = stat($dstPath);
// if ($thumbstat['size'] == 0 || $retval != 0) {
// $result = unlink($dstPath);
//
// if ($result) {
// wfDebugLog('thumbnail',
// sprintf('Removing bad %d-byte thumbnail "%s". unlink() succeeded',
// $thumbstat['size'], $dstPath));
// } else {
// wfDebugLog('thumbnail',
// sprintf('Removing bad %d-byte thumbnail "%s". unlink() failed',
// $thumbstat['size'], $dstPath));
// }
//
// return true;
// }
// }
//
// return false;
// }
//
// /**
// * Remove files from the purge list.
// *
// * This is used by some video handlers to prevent ?action=purge
// * from removing a transcoded video, which is expensive to
// * regenerate.
// *
// * @see LocalFile::purgeThumbnails
// *
// * @param array $files
// * @param array $options Purge options. Currently will always be
// * an array with a single key 'forThumbRefresh' set to true.
// */
// public function filterThumbnailPurgeList(&$files, $options) {
// // Do nothing
// }
//
// /**
// * True if the handler can rotate the media
// * @since 1.24 non-static. From 1.21-1.23 was static
// * @return boolean
// */
// public function canRotate() {
// return false;
// }
//
// /**
// * On supporting image formats, try to read out the low-level orientation
// * of the file and return the angle that the file needs to be rotated to
// * be viewed.
// *
// * This information is only useful when manipulating the original file;
// * the width and height we normally work with is logical, and will match
// * any produced output views.
// *
// * For files we don't know, we return 0.
// *
// * @param File $file
// * @return int 0, 90, 180 or 270
// */
// public function getRotation($file) {
// return 0;
// }
//
// /**
// * Log an error that occurred in an external process
// *
// * Moved from BitmapHandler to MediaHandler with MediaWiki 1.23
// *
// * @since 1.23
// * @param int $retval
// * @param String $err Error reported by command. Anything longer than
// * MediaHandler::MAX_ERR_LOG_SIZE is stripped off.
// * @param String $cmd
// */
// protected function logErrorForExternalProcess($retval, $err, $cmd) {
// # Keep error output limited (bug 57985)
// $errMessage = trim(substr($err, 0, self::MAX_ERR_LOG_SIZE));
//
// wfDebugLog('thumbnail',
// sprintf('thumbnail failed on %s: error %d "%s" from "%s"',
// wfHostname(), $retval, $errMessage, $cmd));
// }
//
// /**
// * Get list of languages file can be viewed in.
// *
// * @param File $file
// * @return String[] Array of language codes, or empty array if unsupported.
// * @since 1.23
// */
// public function getAvailableLanguages(File $file) {
// return [];
// }
//
// /**
// * On file types that support renderings in multiple languages,
// * which language is used by default if unspecified.
// *
// * If getAvailableLanguages returns a non-empty array, this must return
// * a valid language code. Otherwise can return null if files of this
// * type do not support alternative language renderings.
// *
// * @param File $file
// * @return String|null Language code or null if multi-language not supported for filetype.
// * @since 1.23
// */
// public function getDefaultRenderLanguage(File $file) {
// return null;
// }
//
// /**
// * If its an audio file, return the length of the file. Otherwise 0.
// *
// * File::getLength() existed for a long time, but was calling a method
// * that only existed in some subclasses of this class (The TMH ones).
// *
// * @param File $file
// * @return float length in seconds
// * @since 1.23
// */
// public function getLength($file) {
// return 0.0;
// }
//
// /**
// * True if creating thumbnails from the file is large or otherwise resource-intensive.
// * @param File $file
// * @return boolean
// */
// public function isExpensiveToThumbnail($file) {
// return false;
// }
//
// /**
// * Returns whether or not this handler supports the chained generation of thumbnails according
// * to buckets
// * @return boolean
// * @since 1.24
// */
// public function supportsBucketing() {
// return false;
// }
//
// /**
// * Returns a normalised params array for which parameters have been cleaned up for bucketing
// * purposes
// * @param array $params
// * @return array
// */
// public function sanitizeParamsForBucketing($params) {
// return $params;
// }
//
// /**
// * Gets configuration for the file warning message. Return value of
// * the following structure:
// * [
// * // Required, module with messages loaded for the client
// * 'module' => 'example.filewarning.messages',
// * // Required, array of names of messages
// * 'messages' => [
// * // Required, main warning message
// * 'main' => 'example-filewarning-main',
// * // Optional, header for warning dialog
// * 'header' => 'example-filewarning-header',
// * // Optional, footer for warning dialog
// * 'footer' => 'example-filewarning-footer',
// * // Optional, text for more-information link (see below)
// * 'info' => 'example-filewarning-info',
// * ],
// * // Optional, link for more information
// * 'link' => 'http://example.com',
// * ]
// *
// * Returns null if no warning is necessary.
// * @param File $file
// * @return array|null
// */
// public function getWarningConfig($file) {
// return null;
// }
}

@ -0,0 +1,90 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
public class Xomw_MediaHandlerFactory {
// /**
// * Default, MediaWiki core media handlers
// *
// * @var array
// */
// private static $coreHandlers = [
// 'image/jpeg' => JpegHandler::class,
// 'image/png' => PNGHandler::class,
// 'image/gif' => GIFHandler::class,
// 'image/tiff' => TiffHandler::class,
// 'image/webp' => WebPHandler::class,
// 'image/x-ms-bmp' => BmpHandler::class,
// 'image/x-bmp' => BmpHandler::class,
// 'image/x-xcf' => XCFHandler::class,
// 'image/svg+xml' => SvgHandler::class, // official
// 'image/svg' => SvgHandler::class, // compat
// 'image/vnd.djvu' => DjVuHandler::class, // official
// 'image/x.djvu' => DjVuHandler::class, // compat
// 'image/x-djvu' => DjVuHandler::class, // compat
// ];
//
// /**
// * @var array
// */
// private $registry;
//
// /**
// * Instance cache of MediaHandler objects by mimetype
// *
// * @var MediaHandler[]
// */
// private $handlers;
//
// public function __construct( array $registry ) {
// $this->registry = $registry + self::$coreHandlers;
// }
//
// protected function getHandlerClass( $type ) {
// if ( isset( $this->registry[$type] ) ) {
// return $this->registry[$type];
// } else {
// return false;
// }
// }
//
// /**
// * @param String $type mimetype
// * @return boolean|MediaHandler
// */
// public function getHandler( $type ) {
// if ( isset( $this->handlers[$type] ) ) {
// return $this->handlers[$type];
// }
//
// $class = $this->getHandlerClass( $type );
// if ( $class !== false ) {
// /** @var MediaHandler $handler */
// $handler = new $class;
// if ( !$handler->isEnabled() ) {
// wfDebug( __METHOD__ . ": $class is not enabled\n" );
// $handler = false;
// }
// } else {
// wfDebug( __METHOD__ . ": no handler found for $type.\n" );
// $handler = false;
// }
//
// $this->handlers[$type] = $handler;
// return $handler;
// }
}

@ -0,0 +1,607 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
public class Xomw_TransformationalImageHandler {
// /**
// * @param File $image
// * @param array $params Transform parameters. Entries with the keys 'width'
// * and 'height' are the respective screen width and height, while the keys
// * 'physicalWidth' and 'physicalHeight' indicate the thumbnail dimensions.
// * @return boolean
// */
// function normaliseParams( $image, &$params ) {
// if ( !parent::normaliseParams( $image, $params ) ) {
// return false;
// }
//
// # Obtain the source, pre-rotation dimensions
// $srcWidth = $image->getWidth( $params['page'] );
// $srcHeight = $image->getHeight( $params['page'] );
//
// # Don't make an image bigger than the source
// if ( $params['physicalWidth'] >= $srcWidth ) {
// $params['physicalWidth'] = $srcWidth;
// $params['physicalHeight'] = $srcHeight;
//
// # Skip scaling limit checks if no scaling is required
// # due to requested size being bigger than source.
// if ( !$image->mustRender() ) {
// return true;
// }
// }
//
// return true;
// }
//
// /**
// * Extracts the width/height if the image will be scaled before rotating
// *
// * This will match the physical size/aspect ratio of the original image
// * prior to application of the rotation -- so for a portrait image that's
// * stored as raw landscape with 90-degress rotation, the resulting size
// * will be wider than it is tall.
// *
// * @param array $params Parameters as returned by normaliseParams
// * @param int $rotation The rotation angle that will be applied
// * @return array ($width, $height) array
// */
// public function extractPreRotationDimensions( $params, $rotation ) {
// if ( $rotation == 90 || $rotation == 270 ) {
// # We'll resize before rotation, so swap the dimensions again
// $width = $params['physicalHeight'];
// $height = $params['physicalWidth'];
// } else {
// $width = $params['physicalWidth'];
// $height = $params['physicalHeight'];
// }
//
// return [ $width, $height ];
// }
//
// /**
// * Create a thumbnail.
// *
// * This sets up various parameters, and then calls a helper method
// * based on $this->getScalerType in order to scale the image.
// *
// * @param File $image
// * @param String $dstPath
// * @param String $dstUrl
// * @param array $params
// * @param int $flags
// * @return MediaTransformError|ThumbnailImage|TransformParameterError
// */
// function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
// if ( !$this->normaliseParams( $image, $params ) ) {
// return new TransformParameterError( $params );
// }
//
// # Create a parameter array to pass to the scaler
// $scalerParams = [
// # The size to which the image will be resized
// 'physicalWidth' => $params['physicalWidth'],
// 'physicalHeight' => $params['physicalHeight'],
// 'physicalDimensions' => "{$params['physicalWidth']}x{$params['physicalHeight']}",
// # The size of the image on the page
// 'clientWidth' => $params['width'],
// 'clientHeight' => $params['height'],
// # Comment as will be added to the Exif of the thumbnail
// 'comment' => isset( $params['descriptionUrl'] )
// ? "File source: {$params['descriptionUrl']}"
// : '',
// # Properties of the original image
// 'srcWidth' => $image->getWidth(),
// 'srcHeight' => $image->getHeight(),
// 'mimeType' => $image->getMimeType(),
// 'dstPath' => $dstPath,
// 'dstUrl' => $dstUrl,
// 'interlace' => isset( $params['interlace'] ) ? $params['interlace'] : false,
// ];
//
// if ( isset( $params['quality'] ) && $params['quality'] === 'low' ) {
// $scalerParams['quality'] = 30;
// }
//
// // For subclasses that might be paged.
// if ( $image->isMultipage() && isset( $params['page'] ) ) {
// $scalerParams['page'] = intval( $params['page'] );
// }
//
// # Determine scaler type
// $scaler = $this->getScalerType( $dstPath );
//
// if ( is_array( $scaler ) ) {
// $scalerName = get_class( $scaler[0] );
// } else {
// $scalerName = $scaler;
// }
//
// wfDebug( __METHOD__ . ": creating {$scalerParams['physicalDimensions']} " .
// "thumbnail at $dstPath using scaler $scalerName\n" );
//
// if ( !$image->mustRender() &&
// $scalerParams['physicalWidth'] == $scalerParams['srcWidth']
// && $scalerParams['physicalHeight'] == $scalerParams['srcHeight']
// && !isset( $scalerParams['quality'] )
// ) {
//
// # normaliseParams (or the user) wants us to return the unscaled image
// wfDebug( __METHOD__ . ": returning unscaled image\n" );
//
// return $this->getClientScalingThumbnailImage( $image, $scalerParams );
// }
//
// if ( $scaler == 'client' ) {
// # Client-side image scaling, use the source URL
// # Using the destination URL in a TRANSFORM_LATER request would be incorrect
// return $this->getClientScalingThumbnailImage( $image, $scalerParams );
// }
//
// if ( $image->isTransformedLocally() && !$this->isImageAreaOkForThumbnaling( $image, $params ) ) {
// global $wgMaxImageArea;
// return new TransformTooBigImageAreaError( $params, $wgMaxImageArea );
// }
//
// if ( $flags & self::TRANSFORM_LATER ) {
// wfDebug( __METHOD__ . ": Transforming later per flags.\n" );
// $newParams = [
// 'width' => $scalerParams['clientWidth'],
// 'height' => $scalerParams['clientHeight']
// ];
// if ( isset( $params['quality'] ) ) {
// $newParams['quality'] = $params['quality'];
// }
// if ( isset( $params['page'] ) && $params['page'] ) {
// $newParams['page'] = $params['page'];
// }
// return new ThumbnailImage( $image, $dstUrl, false, $newParams );
// }
//
// # Try to make a target path for the thumbnail
// if ( !wfMkdirParents( dirname( $dstPath ), null, __METHOD__ ) ) {
// wfDebug( __METHOD__ . ": Unable to create thumbnail destination " .
// "directory, falling back to client scaling\n" );
//
// return $this->getClientScalingThumbnailImage( $image, $scalerParams );
// }
//
// # Transform functions and binaries need a FS source file
// $thumbnailSource = $this->getThumbnailSource( $image, $params );
//
// // If the source isn't the original, disable EXIF rotation because it's already been applied
// if ( $scalerParams['srcWidth'] != $thumbnailSource['width']
// || $scalerParams['srcHeight'] != $thumbnailSource['height'] ) {
// $scalerParams['disableRotation'] = true;
// }
//
// $scalerParams['srcPath'] = $thumbnailSource['path'];
// $scalerParams['srcWidth'] = $thumbnailSource['width'];
// $scalerParams['srcHeight'] = $thumbnailSource['height'];
//
// if ( $scalerParams['srcPath'] === false ) { // Failed to get local copy
// wfDebugLog( 'thumbnail',
// sprintf( 'Thumbnail failed on %s: could not get local copy of "%s"',
// wfHostname(), $image->getName() ) );
//
// return new MediaTransformError( 'thumbnail_error',
// $scalerParams['clientWidth'], $scalerParams['clientHeight'],
// wfMessage( 'filemissing' )
// );
// }
//
// # Try a hook. Called "Bitmap" for historical reasons.
// /** @var $mto MediaTransformOutput */
// $mto = null;
// Hooks::run( 'BitmapHandlerTransform', [ $this, $image, &$scalerParams, &$mto ] );
// if ( !is_null( $mto ) ) {
// wfDebug( __METHOD__ . ": Hook to BitmapHandlerTransform created an mto\n" );
// $scaler = 'hookaborted';
// }
//
// // $scaler will return a MediaTransformError on failure, or false on success.
// // If the scaler is succesful, it will have created a thumbnail at the destination
// // path.
// if ( is_array( $scaler ) && is_callable( $scaler ) ) {
// // Allow subclasses to specify their own rendering methods.
// $err = call_user_func( $scaler, $image, $scalerParams );
// } else {
// switch ( $scaler ) {
// case 'hookaborted':
// # Handled by the hook above
// $err = $mto->isError() ? $mto : false;
// break;
// case 'im':
// $err = $this->transformImageMagick( $image, $scalerParams );
// break;
// case 'custom':
// $err = $this->transformCustom( $image, $scalerParams );
// break;
// case 'imext':
// $err = $this->transformImageMagickExt( $image, $scalerParams );
// break;
// case 'gd':
// default:
// $err = $this->transformGd( $image, $scalerParams );
// break;
// }
// }
//
// # Remove the file if a zero-byte thumbnail was created, or if there was an error
// $removed = $this->removeBadFile( $dstPath, (boolean)$err );
// if ( $err ) {
// # transform returned MediaTransforError
// return $err;
// } elseif ( $removed ) {
// # Thumbnail was zero-byte and had to be removed
// return new MediaTransformError( 'thumbnail_error',
// $scalerParams['clientWidth'], $scalerParams['clientHeight'],
// wfMessage( 'unknown-error' )
// );
// } elseif ( $mto ) {
// return $mto;
// } else {
// $newParams = [
// 'width' => $scalerParams['clientWidth'],
// 'height' => $scalerParams['clientHeight']
// ];
// if ( isset( $params['quality'] ) ) {
// $newParams['quality'] = $params['quality'];
// }
// if ( isset( $params['page'] ) && $params['page'] ) {
// $newParams['page'] = $params['page'];
// }
// return new ThumbnailImage( $image, $dstUrl, $dstPath, $newParams );
// }
// }
//
// /**
// * Get the source file for the transform
// *
// * @param File $file
// * @param array $params
// * @return array Array with keys width, height and path.
// */
// protected function getThumbnailSource( $file, $params ) {
// return $file->getThumbnailSource( $params );
// }
//
// /**
// * Returns what sort of scaler type should be used.
// *
// * Values can be one of client, im, custom, gd, imext, or an array
// * of Object, method-name to call that specific method.
// *
// * If specifying a custom scaler command with [ Obj, method ],
// * the method in question should take 2 parameters, a File Object,
// * and a $scalerParams array with various options (See doTransform
// * for what is in $scalerParams). On error it should return a
// * MediaTransformError Object. On success it should return false,
// * and simply make sure the thumbnail file is located at
// * $scalerParams['dstPath'].
// *
// * If there is a problem with the output path, it returns "client"
// * to do client side scaling.
// *
// * @param String $dstPath
// * @param boolean $checkDstPath Check that $dstPath is valid
// * @return String|Callable One of client, im, custom, gd, imext, or a Callable array.
// */
// abstract protected function getScalerType( $dstPath, $checkDstPath = true );
//
// /**
// * Get a ThumbnailImage that respresents an image that will be scaled
// * client side
// *
// * @param File $image File associated with this thumbnail
// * @param array $scalerParams Array with scaler params
// * @return ThumbnailImage
// *
// * @todo FIXME: No rotation support
// */
// protected function getClientScalingThumbnailImage( $image, $scalerParams ) {
// $params = [
// 'width' => $scalerParams['clientWidth'],
// 'height' => $scalerParams['clientHeight']
// ];
//
// return new ThumbnailImage( $image, $image->getUrl(), null, $params );
// }
//
// /**
// * Transform an image using ImageMagick
// *
// * This is a stub method. The real method is in BitmapHander.
// *
// * @param File $image File associated with this thumbnail
// * @param array $params Array with scaler params
// *
// * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise
// */
// protected function transformImageMagick( $image, $params ) {
// return $this->getMediaTransformError( $params, "Unimplemented" );
// }
//
// /**
// * Transform an image using the Imagick PHP extension
// *
// * This is a stub method. The real method is in BitmapHander.
// *
// * @param File $image File associated with this thumbnail
// * @param array $params Array with scaler params
// *
// * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise
// */
// protected function transformImageMagickExt( $image, $params ) {
// return $this->getMediaTransformError( $params, "Unimplemented" );
// }
//
// /**
// * Transform an image using a custom command
// *
// * This is a stub method. The real method is in BitmapHander.
// *
// * @param File $image File associated with this thumbnail
// * @param array $params Array with scaler params
// *
// * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise
// */
// protected function transformCustom( $image, $params ) {
// return $this->getMediaTransformError( $params, "Unimplemented" );
// }
//
// /**
// * Get a MediaTransformError with error 'thumbnail_error'
// *
// * @param array $params Parameter array as passed to the transform* functions
// * @param String $errMsg Error message
// * @return MediaTransformError
// */
// public function getMediaTransformError( $params, $errMsg ) {
// return new MediaTransformError( 'thumbnail_error', $params['clientWidth'],
// $params['clientHeight'], $errMsg );
// }
//
// /**
// * Transform an image using the built in GD library
// *
// * This is a stub method. The real method is in BitmapHander.
// *
// * @param File $image File associated with this thumbnail
// * @param array $params Array with scaler params
// *
// * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise
// */
// protected function transformGd( $image, $params ) {
// return $this->getMediaTransformError( $params, "Unimplemented" );
// }
//
// /**
// * Escape a String for ImageMagick's property input (e.g. -set -comment)
// * See InterpretImageProperties() in magick/property.c
// * @param String $s
// * @return String
// */
// function escapeMagickProperty( $s ) {
// // Double the backslashes
// $s = str_replace( '\\', '\\\\', $s );
// // Double the percents
// $s = str_replace( '%', '%%', $s );
// // Escape initial - or @
// if ( strlen( $s ) > 0 && ( $s[0] === '-' || $s[0] === '@' ) ) {
// $s = '\\' . $s;
// }
//
// return $s;
// }
//
// /**
// * Escape a String for ImageMagick's input filenames. See ExpandFilenames()
// * and GetPathComponent() in magick/utility.c.
// *
// * This won't work with an initial ~ or @, so input files should be prefixed
// * with the directory name.
// *
// * Glob character unescaping is broken in ImageMagick before 6.6.1-5, but
// * it's broken in a way that doesn't involve trying to convert every file
// * in a directory, so we're better off escaping and waiting for the bugfix
// * to filter down to users.
// *
// * @param String $path The file path
// * @param boolean|String $scene The scene specification, or false if there is none
// * @throws MWException
// * @return String
// */
// function escapeMagickInput( $path, $scene = false ) {
// # Die on initial metacharacters (caller should prepend path)
// $firstChar = substr( $path, 0, 1 );
// if ( $firstChar === '~' || $firstChar === '@' ) {
// throw new MWException( __METHOD__ . ': cannot escape this path name' );
// }
//
// # Escape glob chars
// $path = preg_replace( '/[*?\[\]{}]/', '\\\\\0', $path );
//
// return $this->escapeMagickPath( $path, $scene );
// }
//
// /**
// * Escape a String for ImageMagick's output filename. See
// * InterpretImageFilename() in magick/image.c.
// * @param String $path The file path
// * @param boolean|String $scene The scene specification, or false if there is none
// * @return String
// */
// function escapeMagickOutput( $path, $scene = false ) {
// $path = str_replace( '%', '%%', $path );
//
// return $this->escapeMagickPath( $path, $scene );
// }
//
// /**
// * Armour a String against ImageMagick's GetPathComponent(). This is a
// * helper function for escapeMagickInput() and escapeMagickOutput().
// *
// * @param String $path The file path
// * @param boolean|String $scene The scene specification, or false if there is none
// * @throws MWException
// * @return String
// */
// protected function escapeMagickPath( $path, $scene = false ) {
// # Die on format specifiers (other than drive letters). The regex is
// # meant to match all the formats you get from "convert -list format"
// if ( preg_match( '/^([a-zA-Z0-9-]+):/', $path, $m ) ) {
// if ( wfIsWindows() && is_dir( $m[0] ) ) {
// // OK, it's a drive letter
// // ImageMagick has a similar exception, see IsMagickConflict()
// } else {
// throw new MWException( __METHOD__ . ': unexpected colon character in path name' );
// }
// }
//
// # If there are square brackets, add a do-nothing scene specification
// # to force a literal interpretation
// if ( $scene === false ) {
// if ( strpos( $path, '[' ) !== false ) {
// $path .= '[0--1]';
// }
// } else {
// $path .= "[$scene]";
// }
//
// return $path;
// }
//
// /**
// * Retrieve the version of the installed ImageMagick
// * You can use PHPs version_compare() to use this value
// * Value is cached for one hour.
// * @return String|boolean Representing the IM version; false on error
// */
// protected function getMagickVersion() {
// $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
// $method = __METHOD__;
// return $cache->getWithSetCallback(
// 'imagemagick-version',
// $cache::TTL_HOUR,
// function () use ( $method ) {
// global $wgImageMagickConvertCommand;
//
// $cmd = wfEscapeShellArg( $wgImageMagickConvertCommand ) . ' -version';
// wfDebug( $method . ": Running convert -version\n" );
// $retval = '';
// $return = wfShellExec( $cmd, $retval );
// $x = preg_match(
// '/Version: ImageMagick ([0-9]*\.[0-9]*\.[0-9]*)/', $return, $matches
// );
// if ( $x != 1 ) {
// wfDebug( $method . ": ImageMagick version check failed\n" );
// return false;
// }
//
// return $matches[1];
// }
// );
// }
//
// /**
// * Returns whether the current scaler supports rotation.
// *
// * @since 1.24 No longer static
// * @return boolean
// */
// public function canRotate() {
// return false;
// }
//
// /**
// * Should we automatically rotate an image based on exif
// *
// * @since 1.24 No longer static
// * @see $wgEnableAutoRotation
// * @return boolean Whether auto rotation is enabled
// */
// public function autoRotateEnabled() {
// return false;
// }
//
// /**
// * Rotate a thumbnail.
// *
// * This is a stub. See BitmapHandler::rotate.
// *
// * @param File $file
// * @param array $params Rotate parameters.
// * 'rotation' clockwise rotation in degrees, allowed are multiples of 90
// * @since 1.24 Is non-static. From 1.21 it was static
// * @return boolean|MediaTransformError
// */
// public function rotate( $file, $params ) {
// return new MediaTransformError( 'thumbnail_error', 0, 0,
// get_class( $this ) . ' rotation not implemented' );
// }
//
// /**
// * Returns whether the file needs to be rendered. Returns true if the
// * file requires rotation and we are able to rotate it.
// *
// * @param File $file
// * @return boolean
// */
// public function mustRender( $file ) {
// return $this->canRotate() && $this->getRotation( $file ) != 0;
// }
//
// /**
// * Check if the file is smaller than the maximum image area for thumbnailing.
// *
// * Runs the 'BitmapHandlerCheckImageArea' hook.
// *
// * @param File $file
// * @param array $params
// * @return boolean
// * @since 1.25
// */
// public function isImageAreaOkForThumbnaling( $file, &$params ) {
// global $wgMaxImageArea;
//
// # For historical reasons, hook starts with BitmapHandler
// $checkImageAreaHookResult = null;
// Hooks::run(
// 'BitmapHandlerCheckImageArea',
// [ $file, &$params, &$checkImageAreaHookResult ]
// );
//
// if ( !is_null( $checkImageAreaHookResult ) ) {
// // was set by hook, so return that value
// return (boolean)$checkImageAreaHookResult;
// }
//
// $srcWidth = $file->getWidth( $params['page'] );
// $srcHeight = $file->getHeight( $params['page'] );
//
// if ( $srcWidth * $srcHeight > $wgMaxImageArea
// && !( $file->getMimeType() == 'image/jpeg'
// && $this->getScalerType( false, false ) == 'im' )
// ) {
// # Only ImageMagick can efficiently downsize jpg images without loading
// # the entire file in memory
// return false;
// }
// return true;
// }
}

@ -15,7 +15,7 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package gplx.xowa.mws.medias; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
import gplx.langs.htmls.*; import gplx.langs.htmls.*;
import gplx.langs.phps.utls.*; import gplx.langs.phps.utls.*;
public class Xomw_mto { public class Xomw_mto {
@ -81,10 +81,10 @@ public class Xomw_mto {
} }
else if (!Php_utl_.Empty(options.custom_title_link)) { else if (!Php_utl_.Empty(options.custom_title_link)) {
// byte[] title = options.custom_title_link; // byte[] title = options.custom_title_link;
link_attribs.Clear(); // link_attribs.Clear();
// link_attribs.Add_many(Gfh_atr_.Bry__href, title.Get_link_url()); // link_attribs.Add_many(Gfh_atr_.Bry__href, title.Get_link_url());
// byte[] options_title = options.title; // byte[] options_title = options.title;
// link_attribs.Add_many(Gfh_atr_.Bry__title, Php_utl_.Empty(options_title) ? title.Get_full_text : options_title; // link_attribs.Add_many(Gfh_atr_.Bry__title, Php_utl_.Empty(options_title) ? title.Get_full_text() : options_title);
} }
else if (!Php_utl_.Empty(options.desc_link)) { else if (!Php_utl_.Empty(options.desc_link)) {
// link_attribs = $this->getDescLinkAttribs( // link_attribs = $this->getDescLinkAttribs(
@ -93,7 +93,7 @@ public class Xomw_mto {
// ); // );
} }
else if (!Php_utl_.Empty(options.file_link)) { else if (!Php_utl_.Empty(options.file_link)) {
link_attribs.Clear(); // link_attribs.Clear();
// link_attribs.Add_many(Gfh_atr_.Bry__href, file.Get_url()); // link_attribs.Add_many(Gfh_atr_.Bry__href, file.Get_url());
} }
else { else {

@ -15,7 +15,7 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package gplx.xowa.mws.medias; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
public class Xomw_mto_params { public class Xomw_mto_params {
public boolean desc_link; public boolean desc_link;
public byte[] alt = null; public byte[] alt = null;

@ -43,6 +43,7 @@ public class Xomw_parser {
private final Btrie_rv trv = new Btrie_rv(); private final Btrie_rv trv = new Btrie_rv();
private int marker_index = 0; private int marker_index = 0;
// private final Xomw_prepro_wkr prepro_wkr = new Xomw_prepro_wkr(); // private final Xomw_prepro_wkr prepro_wkr = new Xomw_prepro_wkr();
public Xomw_parser_env Env() {return env;} private final Xomw_parser_env env = new Xomw_parser_env();
public Xomw_strip_state Strip_state() {return strip_state;} private final Xomw_strip_state strip_state = new Xomw_strip_state(); public Xomw_strip_state Strip_state() {return strip_state;} private final Xomw_strip_state strip_state = new Xomw_strip_state();
public Xomw_sanitizer Sanitizer() {return sanitizer;} private final Xomw_sanitizer sanitizer = new Xomw_sanitizer(); public Xomw_sanitizer Sanitizer() {return sanitizer;} private final Xomw_sanitizer sanitizer = new Xomw_sanitizer();
public Xomw_linker Linker() {return linker;} private final Xomw_linker linker; public Xomw_linker Linker() {return linker;} private final Xomw_linker linker;
@ -75,7 +76,7 @@ public class Xomw_parser {
public void Init_by_wiki(Xowe_wiki wiki) { public void Init_by_wiki(Xowe_wiki wiki) {
linker.Init_by_wiki(wiki.Lang().Lnki_trail_mgr().Trie()); linker.Init_by_wiki(wiki.Lang().Lnki_trail_mgr().Trie());
lnke_wkr.Init_by_wiki(protocols_trie, regex_url, regex_space); lnke_wkr.Init_by_wiki(protocols_trie, regex_url, regex_space);
lnki_wkr.Init_by_wiki(wiki); lnki_wkr.Init_by_wiki(env, wiki);
doubleunder_wkr.Init_by_wiki(doubleunder_data, wiki.Lang()); doubleunder_wkr.Init_by_wiki(doubleunder_data, wiki.Lang());
magiclinks_wkr.Init_by_wiki(); magiclinks_wkr.Init_by_wiki();
} }

@ -0,0 +1,23 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
import gplx.xowa.mws.filerepo.file.*;
public class Xomw_parser_env {
public Xomw_file_finder File_finder() {return file_finder;} private Xomw_file_finder file_finder = new Xomw_file_finder__noop();
public Xomw_parser_env File_finder_(Xomw_file_finder v) {file_finder = v; return this;}
}

@ -22,7 +22,7 @@ import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.xwikis.*;
import gplx.xowa.mws.parsers.*; import gplx.xowa.mws.parsers.quotes.*; import gplx.xowa.mws.parsers.*; import gplx.xowa.mws.parsers.quotes.*;
import gplx.xowa.mws.htmls.*; import gplx.xowa.mws.linkers.*; import gplx.xowa.mws.htmls.*; import gplx.xowa.mws.linkers.*;
import gplx.xowa.mws.utls.*; import gplx.xowa.mws.libs.*; import gplx.xowa.mws.utls.*; import gplx.xowa.mws.libs.*;
import gplx.xowa.mws.filerepos.files.*; import gplx.xowa.mws.filerepo.file.*;
import gplx.xowa.parsers.uniqs.*; import gplx.xowa.parsers.uniqs.*;
/* TODO.XO /* TODO.XO
* P7: multi-line links; // look at the next 'line' to see if we can close it there * P7: multi-line links; // look at the next 'line' to see if we can close it there
@ -43,6 +43,7 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls
// private final Btrie_slim_mgr protocols_trie; // private final Btrie_slim_mgr protocols_trie;
private final Xomw_quote_wkr quote_wkr; private final Xomw_quote_wkr quote_wkr;
private final Xomw_strip_state strip_state; private final Xomw_strip_state strip_state;
private Xomw_parser_env env;
private Xow_wiki wiki; private Xow_wiki wiki;
private Xoa_ttl page_title; private Xoa_ttl page_title;
private final Xomw_linker__normalize_subpage_link normalize_subpage_link = new Xomw_linker__normalize_subpage_link(); private final Xomw_linker__normalize_subpage_link normalize_subpage_link = new Xomw_linker__normalize_subpage_link();
@ -63,7 +64,8 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls
this.tmp = parser.Tmp(); this.tmp = parser.Tmp();
this.strip_state = parser.Strip_state(); this.strip_state = parser.Strip_state();
} }
public void Init_by_wiki(Xow_wiki wiki) { public void Init_by_wiki(Xomw_parser_env env, Xow_wiki wiki) {
this.env = env;
this.wiki = wiki; this.wiki = wiki;
if (title_chars_for_lnki == null) { if (title_chars_for_lnki == null) {
title_chars_for_lnki = (boolean[])Array_.Clone(Xomw_ttl_utl.Title_chars_valid()); title_chars_for_lnki = (boolean[])Array_.Clone(Xomw_ttl_utl.Title_chars_valid());
@ -475,8 +477,7 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls
// MW.HOOK:BeforeParserFetchFileAndTitle // MW.HOOK:BeforeParserFetchFileAndTitle
// Fetch and register the file (file title may be different via hooks) // Fetch and register the file (file title may be different via hooks)
Xomw_file file = new Xomw_file(); Xomw_File file = fetchFileAndTitle(title, null);
file.url = Bry_.new_a7("A.png");
// list($file, $title) = $this->fetchFileAndTitle($title, $options); // list($file, $title) = $this->fetchFileAndTitle($title, $options);
// Get parameter map // Get parameter map
@ -685,6 +686,48 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls
// return $tooltip; // return $tooltip;
// } // }
/**
* Fetch a file and its title and register a reference to it.
* If 'broken' is a key in $options then the file will appear as a broken thumbnail.
* @param Title $title
* @param array $options Array of options to RepoGroup::findFile
* @return array ( File or false, Title of file )
*/
public Xomw_File fetchFileAndTitle(Xoa_ttl title, Hash_adp options) {
Xomw_File file = fetchFileNoRegister(title, options);
//$time = $file ? $file->getTimestamp() : false;
//$sha1 = $file ? $file->getSha1() : false;
//# Register the file as a dependency...
//$this->mOutput->addImage( $title->getDBkey(), $time, $sha1 );
//if ( $file && !$title->equals( $file->getTitle() ) ) {
// # Update fetched file title
// $title = $file->getTitle();
// $this->mOutput->addImage( $title->getDBkey(), $time, $sha1 );
//}
return file;
}
/**
* Helper function for fetchFileAndTitle.
*
* Also useful if you need to fetch a file but not use it yet,
* for example to get the file's handler.
*
* @param Title $title
* @param array $options Array of options to RepoGroup::findFile
* @return File|boolean
*/
private Xomw_File fetchFileNoRegister(Xoa_ttl title, Hash_adp options) {
Xomw_File file = null;
// if ( isset( $options['broken'] ) ) {
// file = false; // broken thumbnail forced by hook
// } elseif ( isset( $options['sha1'] ) ) { // get by (sha1,timestamp)
// file = RepoGroup::singleton()->findFileFromKey( $options['sha1'], $options );
// } else { // get by (name,timestamp)
file = env.File_finder().Find_file(title); // $options
// }
return file;
}
public void Maybe_do_subpage_link(Xomw_linker__normalize_subpage_link rv, byte[] target, byte[] text) { public void Maybe_do_subpage_link(Xomw_linker__normalize_subpage_link rv, byte[] target, byte[] text) {
linker.Normalize_subpage_link(rv, page_title, target, text); linker.Normalize_subpage_link(rv, page_title, target, text);
} }

@ -19,8 +19,11 @@ package gplx.xowa.mws.parsers.lnkis; import gplx.*; import gplx.xowa.*; import g
import org.junit.*; import org.junit.*;
public class Xomw_lnki_wkr__file__tst { public class Xomw_lnki_wkr__file__tst {
private final Xomw_lnki_wkr__fxt fxt = new Xomw_lnki_wkr__fxt(); private final Xomw_lnki_wkr__fxt fxt = new Xomw_lnki_wkr__fxt();
@Before public void init() {fxt.Clear();} @Before public void init() {
fxt.Clear();
fxt.Init__file("A.png", 300, 200);
}
@Test public void Plain() { @Test public void Plain() {
fxt.Test__to_html("[[File:A.png]]", "<img alt='A.png' src='A.png' />"); fxt.Test__to_html("[[File:A.png]]", "<img alt='A.png' src='/orig/7/70/A.png' />");
} }
} }

@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package gplx.xowa.mws.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; import gplx.xowa.mws.parsers.*; package gplx.xowa.mws.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; import gplx.xowa.mws.parsers.*;
import org.junit.*; import org.junit.*; import gplx.xowa.mws.filerepo.*; import gplx.xowa.mws.filerepo.file.*;
public class Xomw_lnki_wkr__text__tst { public class Xomw_lnki_wkr__text__tst {
private final Xomw_lnki_wkr__fxt fxt = new Xomw_lnki_wkr__fxt(); private final Xomw_lnki_wkr__fxt fxt = new Xomw_lnki_wkr__fxt();
@Before public void init() {fxt.Clear();} @Before public void init() {fxt.Clear();}
@ -31,20 +31,29 @@ class Xomw_lnki_wkr__fxt {
private final Xomw_lnki_wkr wkr; private final Xomw_lnki_wkr wkr;
private final Xomw_parser_ctx pctx; private final Xomw_parser_ctx pctx;
private final Xomw_parser_bfr pbfr = new Xomw_parser_bfr(); private final Xomw_parser_bfr pbfr = new Xomw_parser_bfr();
private final Xomw_file_finder__mock file_finder = new Xomw_file_finder__mock();
private final Xomw_FileRepo repo = new Xomw_FileRepo(Bry_.new_a7("/orig"), Bry_.new_a7("/thumb"));
private boolean apos = true; private boolean apos = true;
public Xomw_lnki_wkr__fxt() { public Xomw_lnki_wkr__fxt() {
Xoae_app app = Xoa_app_fxt.Make__app__edit(); Xoae_app app = Xoa_app_fxt.Make__app__edit();
Xowe_wiki wiki = Xoa_app_fxt.Make__wiki__edit(app); Xowe_wiki wiki = Xoa_app_fxt.Make__wiki__edit(app);
Xomw_parser parser = new Xomw_parser(); Xomw_parser parser = new Xomw_parser();
wkr = parser.Lnki_wkr(); wkr = parser.Lnki_wkr();
// env
parser.Env().File_finder_(file_finder);
parser.Init_by_wiki(wiki); parser.Init_by_wiki(wiki);
// ctx
pctx = new Xomw_parser_ctx(); pctx = new Xomw_parser_ctx();
pctx.Init_by_page(wiki.Ttl_parse(Bry_.new_a7("Page_1"))); pctx.Init_by_page(wiki.Ttl_parse(Bry_.new_a7("Page_1")));
} }
public void Clear() { public void Clear() {
wkr.Clear_state(); wkr.Clear_state();
} }
public void Init__file(String title, int w, int h) {
file_finder.Add(title, repo, w, h);
}
public void Test__parse(String src_str, String expd) { public void Test__parse(String src_str, String expd) {
byte[] src_bry = Bry_.new_u8(src_str); byte[] src_bry = Bry_.new_u8(src_str);
wkr.Replace_internal_links(pctx, pbfr.Init(src_bry)); wkr.Replace_internal_links(pctx, pbfr.Init(src_bry));

Loading…
Cancel
Save