你现在正在访问的是萌娘百科用于保存和管理图片、音频等媒体文件的子项目萌娘共享,想要回到萌娘百科,请使用浏览器上的返回按钮、或点击这里
User:Techmoe/mgDuplicateFilesClean.js
注意:在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。
- Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-R(Mac为⌘-R)
- Google Chrome:按Ctrl-Shift-R(Mac为⌘-Shift-R)
- Internet Explorer:按住Ctrl的同时单击刷新,或按Ctrl-F5
- Opera:前往菜单 → 设置(Mac为Opera → Preferences),然后隐私和安全 → 清除浏览数据 → 缓存的图片和文件。
$(window).on('load', function() { if ($(".mw-special-ListDuplicatedFiles")[0] && $('.mw-spcontent > p')[1]) { var mgDuplicateFilesCleanDate = function mgDuplicateFilesCleanDate(timestamp) { var _date = new Date(timestamp); ['getDate', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getUTCDate', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear'].forEach(function(key) { _date[key] = function() { var result = Date.prototype[key].apply(_date, arguments); if (key.includes('Month')) result++; if (typeof result === 'number' && (result + '').length === 1) return '0' + result; else return result + ''; }; }); return _date; }; var mgDuplicateFilesClean = function mgDuplicateFilesClean() { mw.loader.using(["oojs-ui"]).then(function() { var list = $("#picOl, #MP3Ol").find('li').map(function() { return 'File:' + $(this).find('a:first').text(); }).toArray(); var api = new mw.Api(); var duplicateFilesList = {}; var globalusage = {}; var context = $('.mw-spcontent').addClass('duplicateFilesDeletion-context').empty(); context.append('<div class="duplicateFilesDeletion-loading">正在加载中(<span class="duplicateFilesDeletion-loading-step">0</span>/3)……</div>'); $('.duplicateFilesDeletion-loading').css('left', (context.width() - $('.duplicateFilesDeletion-loading').width()) / 2); step = $('.duplicateFilesDeletion-loading-step'); api.post({ action: 'query', format: 'json', titles: list.join('|'), prop: 'duplicatefiles', dflimit: 500 }).then(function(data) { step.text('1'); var _name = []; data = data.query.pages; for (var i in data) { duplicateFilesList[data[i].title] = (data[i].duplicatefiles || []).map(function(n) { if (n.name) n.name = ('File:' + n.name).replace(/_/g, ' '); return n; }); _name.push(data[i].title); } return api.post({ action: 'query', format: 'json', titles: _name.join('|'), prop: 'imageinfo', iiprop: 'timestamp|user|url' }); }).then(function(d) { step.text('2'); var result = d.query.pages; for (var i in result) { duplicateFilesList[result[i].title].push({ name: result[i].title, user: result[i].imageinfo[0].user, timestamp: result[i].imageinfo[0].timestamp, url: result[i].imageinfo[0].url }); } var _name = []; for (var idx in duplicateFilesList) { duplicateFilesList[idx].forEach(function(n) { _name.push(n.name); }); } return api.post({ action: 'query', format: 'json', titles: _name.join('|'), gulimit: 500, prop: 'globalusage' }); }).then(function(d) { step.text('3'); var result = d.query.pages; for (var i in result) { globalusage[result[i].title] = result[i].globalusage; } return Promise.resolve(); }).then(function() { var menuLayout = new OO.ui.MenuLayout({ classes: ['duplicateFilesDeletion-container'] }); context.empty().append(new OO.ui.PanelLayout({ padded: true, expanded: false, framed: true, content: [menuLayout] }).$element); var menuPanel = new OO.ui.PanelLayout({ padded: true, expanded: true, scrollable: true, }), contentPanel = new OO.ui.PanelLayout({ padded: true, expanded: true, scrollable: true }); var selectOption = { items: [] }; var pageLayout = {}; var deletionList = ''; var ifFirstPageLayoutIsAppended = true; for (var i in duplicateFilesList) { selectOption.items.push(new OO.ui.OptionWidget({ data: i, label: i.replace('File:', ''), classes: ['duplicateFilesDeletion-menu-label'] })); pageLayout[i] = new OO.ui.PageLayout({ data: i, padded: true, expanded: true, scrollable: true, classes: ['duplicateFilesDeletion-content-page'] }); pageLayout[i].on('active', function() { menuLayout.$element.height($(this).outerHeight(true)); }); contentPanel.$element.append(pageLayout[i].$element); pageLayout[i].setActive(ifFirstPageLayoutIsAppended); ifFirstPageLayoutIsAppended = false; var fieldset = new OO.ui.FieldsetLayout({ label: '重复文件详细信息' }); fieldset.addItems([ new OO.ui.Element({ classes: ['duplicateFilesDeletion-content-page-introdution'], content: [ new OO.ui.HtmlSnippet('此处显示该组重复文件的详细信息以及使用情况。<br>右侧显示该图片画面,下方显示该组重复文件的信息。<br>已根据情况自动进行默认选择,但<span style="font-weight: bold;">强烈建议</span>您检查一次,以免意外发生。') ] }) ]); var img = []; var flag = { last: null, globaluse: false }; var pageBody = []; duplicateFilesList[i].forEach(function(n) { if (n.url) img.push(new OO.ui.Element({ classes: ['duplicateFilesDeletion-img-preview'], content: [ new OO.ui.HtmlSnippet('<img src="' + n.url + '">') ] })); if (!flag.last) flag.last = { name: n.name + '', timestamp: new Date(n.timestamp).getTime() }; else { var timestamp = new Date(n.timestamp).getTime(); if (timestamp > flag.last.timestamp) flag.last = { name: n.name, timestamp: timestamp }; } var date = mgDuplicateFilesCleanDate(n.timestamp); pageBody.push(new OO.ui.CheckboxInputWidget({ value: n.name + '', data: { uploadTime: date.getFullYear() + '-' + date.getMonth() + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds(), uploader: $('<a/>').addClass("external").attr({ href: '//zh.moegirl.org/User:' + n.user, title: '萌百上的用户 ' + n.user, target: '_blank' }).text('User:' + n.user) } })); if (globalusage[n.name] && globalusage[n.name].length) flag.globaluse = true; }); if (img.length) fieldset.addItems(img); fieldset.addItems(pageBody.map(function(checkbox) { checkbox.on('change', function(b) { var v = checkbox.getValue(); if (b) { if (deletionList.includes(v)) return; else deletionList += v + '|'; } else { if (!deletionList.includes(v)) return; else deletionList.replace(v + '|', ''); } }); var data = checkbox.getData(); var name = checkbox.getValue(); var ifGU = globalusage[name] && globalusage[name].length; if (flag.globaluse) checkbox.setSelected(!ifGU); else checkbox.setSelected(name !== flag.last.name); var filedLayout = new OO.ui.FieldLayout(checkbox, { label: new OO.ui.HtmlSnippet('<a class="external" href="/' + name + '" title=' + name + ' target="_blank">' + name + '</a>'), classes: ['duplicateFilesDeletion-img'] }); var content = $('<div/>'); content.addClass('duplicateFilesDeletion-img-content'); $('<p/>') .append($('<div/>').addClass('duplicateFilesDeletion-img-content-left').text('上传时间:')) .append($('<div/>').addClass('duplicateFilesDeletion-img-content-right').text(data.uploadTime + (name === flag.last.name ? '(这是该组文件最后上传的一份副本)' : ''))) .appendTo(content); $('<p/>') .append($('<div/>').addClass('duplicateFilesDeletion-img-content-left').text('上传者:')) .append($('<div/>').addClass('duplicateFilesDeletion-img-content-right').append(data.uploader)) .appendTo(content); if (ifGU) { var guP = $('<p/>'); guP.append($('<div/>').addClass('duplicateFilesDeletion-img-content-left').text('全域使用页面:')); var guList = $('<div/>').addClass('duplicateFilesDeletion-img-content-right'); globalusage[name].forEach(function(n, i) { var link = $('<a/>'); link.addClass("external").attr({ title: '全域使用页面:' + name, target: '_blank' }); if (n.url) link.attr('href', n.url).text(decodeURI(n.url.substring(1)).replace(/\_/g, ' ')); else { var url = n.wiki = n.wiki ? n.wiki + ':' + n.title : n.title; link.attr('href', '/' + url).text(url); } if (i) guList.append('、'); guList.append(link); }); guP.append(guList).appendTo(content); } filedLayout.$element.append(content); return filedLayout; })); pageLayout[i].$element.append(fieldset.$element); } var select = new OO.ui.SelectWidget(selectOption); selectOption.items[0].setSelected(true); select.on('select', function(item) { var id = item.getData(); for (var i in pageLayout) pageLayout[i].setActive(i === id); }); menuLayout.$menu.append( menuPanel.$element.append('<b>重复文件列表</b>', select.$element) ); menuLayout.$content.append( contentPanel.$element ); }); }); }; function addStyle(css) { return $('<style/>').text(css.replace(/\<[^\>]+\>/g, '')).appendTo('body'); } $.get('https://zh.moegirl.org/User:Techmoe/mgDuplicateFilesClean.css?action=raw&_=' + new Date().getTime(), addStyle); mgDuplicateFilesClean(); /* mw.config.get('mgDuplicateFilesClean ');*/ } });