2023年政策修订增补工作正在进行中,欢迎参与!
  • Moegirl.ICU:萌娘百科流亡社群 581077156(QQ),欢迎对萌娘百科运营感到失望的编辑者加入
  • Moegirl.ICU:账号认领正在试运行,有意者请参照账号认领流程

用戶:Lihaohong/鏡像站

萌娘百科,萬物皆可萌的百科全書!轉載請標註來源頁面的網頁連結,並聲明引自萌娘百科。內容不可商用。
跳至導覽 跳至搜尋

網址:https://moegirl.uk

基本上復刻了萌百的所有功能,除了一方通行等萌派特有的插件。具體情況見首頁。

試圖打開時顯示Argo Tunnel error:伺服器因為某種原因炸了。這是正常現象,請不要試圖掛梯子,因為沒用。伺服器炸的原因可能是:站長住的地方停電了;站長需要重啟電腦;站長住的地方在下大雨,有可能停電,所以提前關機等等。如果伺服器遇到什麼事情導致需要長時間離線(>24小時)會在這裏說明(大概)。

如何重建萌百

伺服器

可以選擇AWS、Linode、Azure等雲服務,也可以像為了省錢的站長一樣用Cloudflare的tunnel把自己的台式機當成伺服器用。

MW的版本可以選1.31,好處是和萌百保持一致。當然,也可以像我一樣選1.38。只要你不拍折騰,就可以在MW 1.38復刻萌百幾乎所有的功能。

選擇nginx+php-fpm的可以參考nginx官網的設置,也可以看看

我自己的設置
orker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        server_name moegirl.uk;
        root /var/www/mediawiki;
        index  index.php;

        client_max_body_size 50m;
        client_body_timeout 60;

        location / {
            try_files $uri $uri/ @rewrite;
        }

        location @rewrite {
            rewrite ^/(.*)$ /index.php?title=$1&$args;
        }

        location ^~ /maintenance/ {
            return 403;
        }

        location /rest.php {
            try_files $uri $uri/ /rest.php?$args;
        }

        location ~ \.php$ {
            include fastcgi.conf;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_param SCRIPT_FILENAME $request_filename;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            try_files $uri /index.php;
            expires max;
            log_not_found off;
        }

        location = /_.gif {
            expires max;
            empty_gif;
        }

        location ^~ /cache/ {
            deny all;
        }

        location /dumps {
            root /var/www/mediawiki/local;
            autoindex on;
        }
    }
}

注意:fastcgi_pass應該和php-fpm的設置保持一致。要麼都是127.0.0.1:端口,要麼都是某個文件。

插件

對着Special:版本安裝就行。跳過所有的萌派插件(難道你也想整個一方通行?)。如果不想專門搞個圖站,可以不裝GlobalBlocking和Global Usage。RegexParserFunctions不支持新版MW,所以要用RegexFun代替。

不少插件需要額外的調整。大多數調整都可以通過LocalSettings.php做,但是少部分需要手動做,例如Special:Interwiki(或許可以自動化,但是太麻煩了)。

LocalSettings.php

點擊查看我自己的設置(不是完全照搬萌百)
<?php

# Protect against web entry
if ( !defined( 'MEDIAWIKI' ) ) {
	exit;
}
// error_reporting( E_ALL );
// ini_set( 'display_errors', 1 );


## Uncomment this to disable output compression
# $wgDisableOutputCompression = true;

$wgSitename = "萌娘百科";

## The URL base path to the directory containing the wiki;
## default/var/www/mediawiki/includes/libs/rdbms/database/Database.phps for all runtime URL paths are based off of this.
## For more information on customizing the URLs
## (like /w/index.php/Page_title to /wiki/Page_title) please see:
## https://www.mediawiki.org/wiki/Manual:Short_URL
$wgScriptPath = "";
$wgArticlePath = "/$1";
$wgUsePathInfo = true;
$wgScriptExtension = true;

## The protocol and server name to use in fully-qualified URLs
$wgServer = "https://moegirl.uk";

## The URL path to static resources (images, scripts, etc.)
$wgResourceBasePath = $wgScriptPath;

## The URL paths to the logo.  Make sure you change this from the default,
## or else you'll overwrite your logo when you upgrade!
$wgLogo = $wgScriptPath . '/images/1/1f/钻地.png';

## UPO means: this is also a user preference option

$wgEnableEmail = false;
$wgEnableUserEmail = true; # UPO

$wgEmergencyContact = "apache@🌻.invalid";
$wgPasswordSender = "apache@🌻.invalid";

$wgEnotifUserTalk = false; # UPO
$wgEnotifWatchlist = false; # UPO
$wgEmailAuthentication = true;

## Database settings
$wgDBtype = "mysql";
$wgDBserver = "localhost";
$wgDBname = "mgp";
$wgDBuser = "";
$wgDBpassword = "";

# MySQL specific settings
$wgDBprefix = "";

# MySQL table options to use during installation or update
$wgDBTableOptions = "ENGINE=InnoDB, DEFAULT CHARSET=binary";

# Shared database table
# This has no effect unless $wgSharedDB is also set.
$wgSharedTables[] = "actor";

## Shared memory settings
$wgMainCacheType = CACHE_NONE;
$wgMemCachedServers = [];

## To enable image uploads, make sure the 'images' directory
## is writable, then set this to true:
$wgEnableUploads = true;
$wgFileExtensions = ['ogg', 'ogv', 'oga', 'flac', 'opus', 'wav', 'webm', 'mp3', 
    'png', 'gif', 'jpg', 'jpeg', 'webp', 'svg',
    'pdf', 'jp2', 'ttf', 'mp4'];
$wgHooks['MimeMagicInit'][] = static function ( $mime ) {
    $mime->addExtraTypes( 'font/sfnt ttf');
};
$wgAllowCopyUploads = true;
$wgCopyUploadsFromSpecialUpload = true;
$wgGroupPermissions['user']['upload_by_url'] = true;
$wgMaxUploadSize = 50 *1024 * 1024;
$wgUploadSizeWarning = 0;

$wgUseImageMagick = false;
// $wgImageMagickConvertCommand = "/usr/bin/convert";
// $wgThumbnailEpoch = 20221013100107;
$wgAllowTitlesInSVG = true;
$wgSVGConverter = 'rsvg';
$wgSVGConverters = ['rsvg' => '/usr/bin/rsvg-convert -w $width -h $height $input -o $output'];
$wgUseImageResize = false;


# InstantCommons allows wiki to use images from https://commons.wikimedia.org
$wgUseInstantCommons = false;

$wgReferrerPolicy = "no-referrer";
// $wgForeignFileRepos[] = [
// 	'class' => ForeignAPIRepo::class,
// 	'name' => 'commons', // Must be a distinct name
// 	'apibase' => 'https://commons.moegirl.org.cn/api.php',
// 	'hashLevels' => 2,
// 	'fetchDescription' => true, // Optional
// 	'descriptionCacheExpiry' => 0, // 12 hours, optional (values are seconds)
// 	'apiThumbCacheExpiry' => 0, // 24 hours, optional, but required for local thumb caching
// 	'transformVia404' => true
// ];
// $wgNativeImageLazyLoading = true;
// $wgGenerateThumbnailOnParse = false;
// $wgThumbnailScriptPath = "$wgScriptPath/thumb.php";

// $wgForeignFileRepos[] = [
// 	'class' => FileRepo::class,
// 	'name' => 'sharedFsRepo',
// 	'directory' => '/home/lihaohong/Documents/images',
// 	'hashLevels' => 0,
// 	// 'url' => 'https://shared.example.org/path/to/uploads/',
// ];

# Periodically send a pingback to https://www.mediawiki.org/ with basic data
# about this MediaWiki instance. The Wikimedia Foundation shares this data
# with MediaWiki developers to help guide future development efforts.
$wgPingback = true;

# Site language code, should be one of the list in ./languages/data/Names.php
$wgLanguageCode = "zh";
$wgDisabledVariants = array( 'zh-mo', 'zh-my' );
# Time zone
$wgLocaltimezone = "UTC";

$wgRestrictDisplayTitle = false;

$wgMaxNameChars = 50;

$wgAllowUserCss = true;
$wgAllowUserJs = true;

## Set $wgCacheDirectory to a writable directory on the web server
## to make your wiki go slightly faster. The directory should not
## be publicly accessible from the web.
#$wgCacheDirectory = "$IP/cache";

$wgSecretKey = "";

# Changing this will log out all existing sessions.
$wgAuthenticationTokenVersion = "1";

# Site upgrade key. Must be set to a string (default provided) to turn on the
# web installer while LocalSettings.php is in place
$wgUpgradeKey = "";

## For attaching licensing metadata to pages, and displaying an
## appropriate copyright notice / icon. GNU Free Documentation
## License and Creative Commons licenses are supported so far.
$wgRightsPage = ""; # Set to the title of a wiki page that describes your license/copyright
$wgRightsUrl = "https://creativecommons.org/licenses/by-nc-sa/3.0/";
$wgRightsText = "Creative Commons Attribution-NonCommercial-ShareAlike";
$wgRightsIcon = "$wgResourceBasePath/resources/assets/licenses/cc-by-nc-sa.png";

# Path to the GNU diff3 utility. Used for conflict resolution.
$wgDiff3 = "/usr/bin/diff3";

# The following permissions were set based on your choice in the installer
$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['read'] = false;
$wgGroupPermissions['*']['createtalk'] = false;
$wgGroupPermissions['*']['createpage'] = false;
$wgWhitelistRead = ['Mainpage', '首页', 'Mainpage2', 'Help:关于萌娘百科镜像站的账户创建申请与被申请这件事'];

## Default skin: you can change the default skin. Use the internal symbolic
## names, e.g. 'vector' or 'monobook':
$wgDefaultSkin = "vector";

# Enabled skins.
# The following skins were automatically enabled:
wfLoadSkin( 'MinervaNeue' );
# wfLoadSkin( 'MonoBook' );
# wfLoadSkin( 'Timeless' );
wfLoadSkin( 'Vector' );
# wfLoadSkin( 'MoeSkin' );


# Enabled extensions. Most of the extensions are enabled by adding
# wfLoadExtension( 'ExtensionName' );
# to LocalSettings.php. Check specific extension documentation for more details.
# The following extensions were automatically enabled:
wfLoadExtension( 'AbuseFilter' );
wfLoadExtension( 'CategoryTree' );
wfLoadExtension( 'Gadgets' );
wfLoadExtension( 'Nuke' );
wfLoadExtension( 'OATHAuth' );
wfLoadExtension( 'Poem' );
wfLoadExtension( 'ReplaceText' );
wfLoadExtension( 'Scribunto' );
wfLoadExtension( 'TitleBlacklist' );
wfLoadExtension( 'WikiEditor' );

# wfLoadExtension( 'VisualEditor' );

wfLoadExtension( 'Avatar' );
wfLoadExtension( 'AJAXPoll' );
wfLoadExtension( 'Cite' );
wfLoadExtension( 'intersection' );
wfLoadExtension( 'InputBox' );
wfLoadExtension( 'Loops' );
wfLoadExtension( 'Echo' );
wfLoadExtension( 'ParserFunctions' );
wfLoadExtension( 'RandomSelection' );

wfLoadExtension( 'TemplateStyles' );
$wgTemplateStylesAllowedUrls = [
    "audio" => [
        "<^https://upload\\.wikimedia\\.org/wikipedia/commons/>"
    ],
    "image" => [
        "<.*>"
    ],
    "svg" => [
        "<^https://upload\\.wikimedia\\.org/wikipedia/commons/[^?#]*\\.svg(?:[?#]|$)>"
    ],
    "font" => [],
    "namespace" => [
        "<.>"
    ],
    "css" => []
];
$wgTemplateStylesNamespaces = [
    NS_TEMPLATE => true,
	NS_MAIN => true,
	828 => true
];


wfLoadExtension( 'Variables' );

wfLoadExtension( 'Widgets' );
// unset( $wgGroupPermissions['widgeteditor'] );
unset( $wgRevokePermissions['widgeteditor'] );
unset( $wgAddGroups['widgeteditor'] );
unset( $wgRemoveGroups['widgeteditor'] );
unset( $wgGroupsAddToSelf['widgeteditor'] );
unset( $wgGroupsRemoveFromSelf['widgeteditor'] );
$wgGroupPermissions['sysop']['editwidgets'] = true;

$wgIncludeLegacyJavaScript = true;
$wgLegacyJavaScriptGlobals = true;
// $wgResourceLoaderDebug = true;

$wgResourceLoaderMaxage = [
    'versioned' => 1 * 60,
    'unversioned' => 1 * 60
];

wfLoadExtension( 'FlowThread' );
$wgFlowThreadConfig['Avatar'] = '/extensions/Avatar/avatar.php?user=${username}';

wfLoadExtension( 'Interwiki' );
// To grant sysops permissions to edit interwiki data
$wgGroupPermissions['sysop']['interwiki'] = true;
$wgInterwikiMagic = true;
$wgHideInterlanguageLinks = false;

wfLoadExtension( 'CharInsert' );

wfLoadExtension( 'CheckUser' );
$wgCheckUserEnableSpecialInvestigate = true;
$wgGroupPermissions['bureaucrat']['checkuser'] = false;
$wgGroupPermissions['bureaucrat']['checkuser-log'] = false;
$wgGroupPermissions['bureaucrat']['investigate'] = false;
$wgGroupPermissions['checkuser']['checkuser'] = false;
$wgGroupPermissions['checkuser']['checkuser-log'] = false;

require_once "$IP/extensions/RegexFun/RegexFun.php";
# wfLoadExtension ( 'RegexParserFunctions' );
# require_once('extensions/RegexParserFunctions/RegexParserFunctions.php');

wfLoadExtension( 'ImageMap' );
$wgAllowExternalImages = true;
$wgAllowImageTag = true;

wfLoadExtension( 'ContributionScores' );
// Exclude Bots from the reporting - Can be omitted.
$wgContribScoreIgnoreBots = true; 
// Exclude Blocked Users from the reporting - Can be omitted.
$wgContribScoreIgnoreBlockedUsers = true;
// Exclude specific usernames from the reporting - Can be omitted.
$wgContribScoreIgnoreUsernames = [];
// Use real user names when available - Can be omitted. Only for MediaWiki 1.19 and later.
$wgContribScoresUseRealName = true;
// Set to true to disable cache for parser function and inclusion of table.
$wgContribScoreDisableCache = false;
// Use the total edit count to compute the Contribution score.
$wgContribScoreUseRoughEditCount = false;   
// Each array defines a report - 7,50 is "past 7 days" and "LIMIT 50" - Can be omitted.
$wgContribScoreReports = [
    [ 7, 50 ],
    [ 30, 50 ],
    [ 0, 50 ]
];

wfLoadExtension( 'Thanks' );
wfLoadExtension( 'WikiLove' );

wfLoadExtension('PinyinSort');
$wgCategoryCollation = 'pinyin';

wfLoadExtension( 'Disambiguator' );

wfLoadExtension( 'Elastica' );
wfLoadExtension( 'CirrusSearch' );
# $wgDisableSearchUpdate = true;
$wgSearchType = 'CirrusSearch';

wfLoadExtension( 'DeleteBatch' );
$wgGroupPermissions['bureaucrat']['deletebatch'] = false;
$wgGroupPermissions['sysop']['deletebatch'] = true;

wfLoadExtension( 'MassEditRegex' );
$wgGroupPermissions['sysop']['masseditregex'] = true;

wfLoadExtension( 'Renameuser' );
wfLoadExtension( 'TemplateSandbox' );
$wgTemplateSandboxEditNamespaces[] = 828;

wfLoadExtension( 'UserMerge' );
$wgGroupPermissions['bureaucrat']['usermerge'] = true;

wfLoadExtension( 'CodeEditor' );
$wgDefaultUserOptions['usebetatoolbar'] = 1; // user option provided by WikiEditor extension

wfLoadExtension('Sm2Shim');
wfLoadExtension( 'TimedMediaHandler' );
$wgFFmpegLocation = '/usr/bin/ffmpeg'; // Most common ffmpeg path on Linux

wfLoadExtension( 'AntiSpoof' );

wfLoadExtensions([ 'ConfirmEdit', 'ConfirmEdit/QuestyCaptcha' ]);
$wgCaptchaQuestions = [
];
$wgCaptchaTriggers['edit']          = true;
$wgCaptchaTriggers['create']        = true;
$wgCaptchaTriggers['createtalk']    = true;


wfLoadExtension( 'SpamBlacklist' );

wfLoadExtension( 'MobileFrontend' );
$wgDefaultMobileSkin = 'minerva';

wfLoadExtension( 'MultiBoilerplate' );
wfLoadExtension( 'MultimediaViewer' );
wfLoadExtension( 'Popups' );
wfLoadExtension( 'RelatedArticles' );
wfLoadExtension( 'RevisionSlider' );
wfLoadExtension( 'TextExtracts' );

wfLoadExtension( 'GTag' );
$wgGTagAnalyticsId = 'G-5BYLGNG6WR';

# putenv("GDFONTPATH=/usr/share/fonts/opentype/noto");
wfLoadExtension( "timeline" );
# putenv("GDFONTPATH=/usr/share/fonts/opentype/noto");
$wgTimelineFontFile = '/usr/share/fonts/truetype/freefont/FreeSans.ttf';
# $wgTimelineFontFile = '/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc';
# ns aliases
$wgNamespaceAliases = [
	'T' => NS_TEMPLATE,
	'U' => NS_USER,
	'H' => NS_HELP,
	'CAT' => NS_CATEGORY,
	'MGP' => 4,
    'MW' => NS_MEDIAWIKI
];

$wgShowExceptionDetails = true;

$wgAutoConfirmAge = 3600 * 12;
$wgAutoConfirmCount = 5;

$wgGroupPermissions['user']['editcontentmodel'] = false;
$wgGroupPermissions['user']['move-categorypages'] = false;
$wgGroupPermissions['user']['movefile'] = false;
$wgGroupPermissions['user']['move-rootuserpages'] = false;
$wgGroupPermissions['user']['move'] = false;
$wgGroupPermissions['user']['move-subpages'] = false;
$wgGroupPermissions['user']['reupload'] = false;

$wgGroupPermissions['autoconfirmed']['upload_by_url'] = true;
$wgGroupPermissions['autoconfirmed']['skipcaptcha'] = true;
$wgGroupPermissions['autoconfirmed']['move-categorypages'] = true;
$wgGroupPermissions['autoconfirmed']['movefile'] = true;
$wgGroupPermissions['autoconfirmed']['move-rootuserpages'] = true;
$wgGroupPermissions['autoconfirmed']['move'] = true;
$wgGroupPermissions['autoconfirmed']['move-subpages'] = true;
$wgGroupPermissions['autoconfirmed']['editcontentmodel'] = true;
$wgGroupPermissions['autoconfirmed']['transcode-reset'] = true;

$wgGroupPermissions['manually-confirmed']['autoconfirmed'] = true;
$wgGroupPermissions['manually-confirmed']['skipcaptcha'] = true;
$wgGroupPermissions['manually-confirmed']['editsemiprotected'] = true;

$wgGroupPermissions['flood']['noratelimit'] = true;
$wgGroupPermissions['flood']['bot'] = true;
$wgGroupsRemoveFromSelf['flood'] = ['flood'];

$wgGroupPermissions['bot']['noratelimit'] = true;
$wgGroupPermissions['bot']['skipcaptcha'] = true;
$wgGroupPermissions['bot']['move-categorypages'] = true;
$wgGroupPermissions['bot']['movefile'] = true;
$wgGroupPermissions['bot']['move-rootuserpages'] = true;
$wgGroupPermissions['bot']['move'] = true;
$wgGroupPermissions['bot']['move-subpages'] = true;
$wgGroupPermissions['bot']['suppressredirect'] = true;
$wgGroupPermissions['bot']['editsemiprotected'] = true;

$wgGroupPermissions['goodeditor']['autopatrol'] = true;
$wgGroupPermissions['goodeditor']['patrolmarks'] = true;
$wgGroupPermissions['goodeditor']['reupload-own'] = true;
$wgGroupPermissions['honoredmaintainer'] = $wgGroupPermissions['goodeditor'];

$wgGroupPermissions['patroller'] = $wgGroupPermissions['goodeditor'];
$wgGroupPermissions['patroller']['commentadmin-restricted'] = true;
$wgGroupPermissions['patroller']['noratelimit'] = true;
$wgGroupPermissions['patroller']['apihighlimits'] = true;
$wgGroupPermissions['patroller']['rollback'] = true;
$wgGroupPermissions['patroller']['skipcaptcha'] = true;
$wgGroupPermissions['patroller']['unwatchedpages'] = true;
$wgGroupPermissions['patroller']['patrol'] = true;
$wgGroupPermissions['patroller']['suppressredirect'] = true;
$wgGroupPermissions['patroller']['patrolleredit'] = true;
$wgGroupPermissions['patroller']['reupload'] = true;
$wgGroupPermissions['patroller']['block'] = true;
$wgAddGroups['patroller'] = ['goodeditor'];
$wgRemoveGroups['patroller'] = ['goodeditor'];

$wgRestrictionLevels[] = 'patrolleredit';
$wgRestrictionLevels[] = 'techedit';

$wgGroupPermissions['interface-admin']['techedit'] = true;

$wgGroupPermissions['techeditor']['techedit'] = true;
$wgGroupPermissions['techeditor']['reupload'] = true;

$wgGroupPermissions['scripteditor'] = $wgGroupPermissions['techeditor'];
$wgGroupPermissions['scripteditor']['editwidgets'] = true;

$wgGroupPermissions['abusefilter-maintainer']['abusefilter-modify'] = true;
$wgGroupPermissions['abusefilter-maintainer']['abusefilter-modify-restricted'] = true;
$wgGroupPermissions['abusefilter-maintainer']['abusefilter-revert'] = true;
$wgGroupPermissions['abusefilter-maintainer']['abusefilter-log-private'] = true;

$wgGroupPermissions['sysop'] = array_merge($wgGroupPermissions['sysop'], $wgGroupPermissions['patroller']);
$wgGroupPermissions['sysop']['deleterevision'] = true;
$wgGroupPermissions['sysop']['techedit'] = true;
$wgAddGroups['sysop'] = ['goodeditor', 'patroller', 'flood', 'manually-confirmed', 'techeditor'];
$wgRemoveGroups['sysop'] = ['goodeditor', 'honoredmaintainer', 'flood', 'manually-confirmed', 'techeditor'];
$wgGroupsAddToSelf['sysop'] = ['interface-admin'];
$wgGroupsRemoveFromSelf['sysop'] = ['interface-admin'];

$wgGroupPermissions['kanbanmusume'] = $wgGroupPermissions['goodeditor'];
$wgGroupsRemoveFromSelf['kanbanmusume'] = ['kanbanmusume'];

unset( $wgGroupPermissions['push-subscription-manager'] );
unset( $wgRevokePermissions['push-subscription-manager'] );
unset( $wgAddGroups['push-subscription-manager'] );
unset( $wgRemoveGroups['push-subscription-manager'] );
unset( $wgGroupsAddToSelf['push-subscription-manager'] );
unset( $wgGroupsRemoveFromSelf['push-subscription-manager'] );

$wgExtensionFunctions[] = function() {
	global $wgGroupPermissions;
	unset( $wgGroupPermissions['widgeteditor'] );
	unset( $wgGroupPermissions['push-subscription-manager'] );
};

搬運全部頁面

MW 1.38可以直接導入鏡像站的dump。

  1. 2022年11月1日的dump。包含了與萌百在2022年9月23日同步的歷史記錄。
  2. 2022年11月18日的dump。僅包含最新版本。因已與萌百同步,可能包含已被和諧的內容。

Widget

新版本MW中所有依賴jQuery和mw.loader.using的Widget全廢。可以把它們手動轉移到Gadget,也可以像bwiki一樣改用script標籤手動加載js。但是最好的方法還是用一個數組放所有依賴的名字和函數。具體見鏡像站相關頁面

其它bug修復

想要評論區可以裝FlowThread插件,但是因為某個bug無法關評論區(見GitHub),需要手動修復。

ContributionScores也有bug。

MW自帶的Sanitizer/StylePropertySanitizer.php需要允許transform屬性中使用perspective(...)