Thành viên:NguoiDungKhongDinhDanh/script-imageres.js

Chú ý: Sau khi lưu thay đổi trang, bạn phải xóa bộ nhớ đệm của trình duyệt để nhìn thấy các thay đổi. Google Chrome, Firefox, Internet ExplorerSafari: Giữ phím ⇧ Shift và nhấn nút Reload/Tải lại trên thanh công cụ của trình duyệt. Để biết chi tiết và hướng dẫn cho các trình duyệt khác, xem Trợ giúp:Xóa bộ nhớ đệm.

/** <nowiki>
 * Ghi công: [[:en:User:Alex 21/script-imageres.js]]
 * Cách cài đặt: Thêm dòng dưới đây vào trang common.js của bạn:

mw.loader.load('/w/index.php?title=User:NguoiDungKhongDinhDanh/script-imageres.js&action=raw&ctype=text/javascript');

 * Lưu ý: Khi script đang chạy, đừng đóng thẻ hay tải lại trang. 
**/

/* jshint esversion: 6, maxerr: 9999, undef: true, unused: true, quotmark: single */
/* globals $, mw */

$(function() {
	var namespace = mw.config.get('wgNamespaceNumber');
	var database = mw.config.get('wgDBname');
	
	if (namespace !== 6 || database !== 'viwiki') {
		return;
	}
	
	var pageName = mw.config.get('wgPageName');
	var title = mw.config.get('wgTitle');
	var groups = mw.config.get('wgUserGroups');
	
	var api = new mw.Api();
	var ad = ' ([[User:NguoiDungKhongDinhDanh/script-imageres.js|Imageres]])';
	var isAdmin = groups.includes('eliminator') || groups.includes('sysop');
	var maxPixels = 200000;
	
	var templates = [
		'Tập tin không tự do cần giảm độ phân giải',
		'Giảm tập tin không tự do',
		'Giảm không tự do',
		'Non-free reduce'
		// 'Tập tin không tự do có phiên bản cũ',
		// 'Tập tin có phiên bản cũ không tự do',
		// 'Orphaned non-free revisions',
		// 'Orfurrev'
	];
	var tempRegExp = function(t = templates) {
		var aliases = t.map(
			e => `[${e[0]}${e[0].toLowerCase()}]${e.slice(1).replace(/ /g, '[_ ]+')}`
		).concat((function() {
			var a = ['thành viên', 'user'].map(
				e => [...e].map(f => f.trim() ? `[${f.toUpperCase()}${f}]` : '[_ ]+').join('')
			).join('|');
			return `(?:${a})\s*:\s*[Ll]RBot/resize`;
		})()).join('|');
		return new RegExp(`\\{\\{\s*(?:${aliases})\s*(?:\\|[^}]*)?\\}\\}`, 'g');
	};
	
	function format(x) {
		return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.');
	}
	function notify(content, tag, autoHide = true, type = null) {
		mw.notify(content, {
			type: type,
			autoHide: autoHide,
			autoHideSeconds: 10,
			tag: `imageres-${tag}`
		});
	}
	function fail(response, tag) {
		notify(`Tác vụ thất bại. Lỗi API: ${response.error.info}`, tag, true, 'warn');
	}
	
	function reupload(newImageLink) {
		notify('Đang tải lên...', 'uploading', false);
		
		api.postWithToken('csrf', {
			action: 'upload',
			filename: title,
			comment: 'Giảm kích thước xuống mức nhỏ hơn 0.2 MP theo [[WP:IMAGERES|quy định]].' + ad,
			ignorewarnings: true,
			url: newImageLink,
			format: 'json',
			formatversion: 2
		}).done(function() {
			notify('Tải lên thành công.', 'uploading', true, 'success');
			
			if (isAdmin) {
				revdel();
			} else {
				tempmodify();
			}
		}).fail(function(error, response) {
			fail(response, 'uploading');
		});
	}
	function revdel() {
		notify('Đang tiến hành xoá phiên bản cũ của tập tin...', 'revdeling', false);
		
		api.get({
			action: 'query',
			titles: pageName,
			prop: ['imageinfo'],
			iiprop: ['timestamp', 'archivename'],
			iilimit: 500,
			iilocalonly: true,
			format: 'json',
			formatversion: 2
		}).done(function(response) {
			var ids = response.query.pages[0].imageinfo.reduce(
				(p, c) => (!c.archivename || p.push(c.archivename.split('!')[0])) && p, []
			);
			
			if (!ids.length) {
				notify('Không có phiên bản cũ.', 'revdeling', true, 'warn');
				return;
			}
			
			api.postWithToken('csrf', {
				action: 'revisiondelete',
				type: 'oldimage',
				target: pageName,
				ids: ids,
				hide: ['content'],
				reason: 'Nội dung không tự do không được sử dụng.' + ad,
				format: 'json',
				formatversion: 2
			}).done(function() {
				notify('Xoá thành công.', 'revdeling', true, 'success');
				tempmodify();
			}).fail(function(error, response) {
				fail(response, 'revdeling');
			});
		}).fail(function(error, response) {
			notify(`Truy vấn thông tin thất bại. Lỗi API: ${response.error.info}`, 'gen', true, 'warn');
		});
	}
	function tempmodify() {
		notify('Đang thêm/gỡ bản mẫu...', 'tempremoving', false);
		
		api.get({
			action: 'query',
			titles: [pageName],
			prop: ['revisions'],
			rvprop: ['content'],
			rvslots: ['main'],
			rvlimit: 1,
			format: 'json',
			formatversion: 2
		}).done(function(response) {
			var text = response.query.pages[0].revisions[0].slots.main.content;
			var newText = text.replace(tempRegExp(), '');
			
			var regexp = tempRegExp([
				'Tập tin không tự do có phiên bản cũ',
				'Tập tin có phiên bản cũ không tự do',
				'Orphaned non-free revisions',
				'Orfurrev'
			]);
			
			if (!isAdmin && !regexp.test(newText)) {
				newText = '{{Tập tin không tự do có phiên bản cũ}}\n\n' + newText;
			} else if (isAdmin) {
				newText = newText.replace(regexp, '');
			}
			
			if (text === newText) {
				notify('Không tìm thấy bản mẫu.', 'tempremoving', true);
				return;
			}
			
			api.postWithToken('csrf', {
				action: 'edit',
				title: pageName,
				text: newText.replace(/(?:\n\s*){3,}/g, '').trim(),
				summary: 'Đã giảm độ phân giải/đã xoá bản mẫu.' + ad,
				minor: true,
				nocreate: true,
				format: 'json',
				formatversion: 2
			}).done(function() {
				notify('Đã thêm/gỡ bản mẫu.', 'tempremoving', true, 'success');
			}).fail(function(error, response) {
				fail(response, 'tempremoving');
			});
		}).fail(function(error, response) {
			fail(response, 'tempremoving');
		});
	}
	
	$('.fileInfo').ready(function() {
		var $fileInfo = $('.fileInfo');
		
		if (!$fileInfo) {
			return;
		}
		
		var hw = $fileInfo.html().match(/([\d\.]+)×([\d\.]+)/);
	
		var width = parseInt(hw[1].replace(/\./g, ''));
		var height = parseInt(hw[2].replace(/\./g, ''));
		var pixels = height * width;
		
		var newWidth = Math.floor(Math.sqrt(maxPixels * width / height));
		var newHeight = Math.round(height * newWidth / width);
		var newPixels;
		
		while ((newPixels = newWidth * newHeight) > maxPixels) {
			--newWidth;
			newHeight = Math.round(height * newWidth / width);
		}
		
		var tagStart = `<strong style="color: ${pixels > maxPixels ? 'red' : 'green'};">`;
		var tagEnd = '</strong>';
		
		$fileInfo.html(
			$fileInfo.html().replace(
				/([\d\.]+)×([\d\.]+)/,
				`${width} × ${height} = ${tagStart}${format(pixels)}${tagEnd}`
			)
		);
		
		$('.internal').text($('.internal').text().replace(/_/g, ' '));
		
		var imageLink = $('.internal').first().attr('href');
		var newImageLink = `https:${
			imageLink.replace('/vi/', '/vi/thumb/')
		}/${newWidth}px-${imageLink.match(/(?<=\/)[^\/]+$/)[0]}`;
		
		var placeholder = (
			$('#mw-imagepage-reupload-link > a').attr('href') +
			'&wpUploadDescription=Giảm độ phân giải xuống mức nhỏ hơn 0.2 MP theo [[User:LRBot|quy định]].'
		);
		
		$fileInfo.html(
			$fileInfo.html() + '<br>' +
			'<dd>' +
				'Độ phân giải tối đa: ' +
				`${tagStart}${newWidth} × ${newHeight}${tagEnd} = ${format(newPixels)} điểm ảnh ${
					pixels <= maxPixels ? '' : (
						`<span>(<a href="${newImageLink}">hình đã giảm</a>)</span> ` +
						`<span>(<a class="imageres-links" id="imageres-upload" href="${placeholder}">tải lên lại</a>)</span> `
					)
				}${
					isAdmin ? '<span>(<a class="imageres-links" id="imageres-revdel">xoá bản cũ</a>)</span> ' : ''
				}` +
				'<span>(<a class="imageres-links" id="imageres-temprm">gỡ bản mẫu</a>)</span>' +
			'</dd>'
		);
		
		$('.imageres-links').click(function(e) {
			e.preventDefault();
			$(this).parent().remove();
		});
		
		$('#imageres-upload').click(function() {
			reupload(newImageLink);
		});
		$('#imageres-revdel').click(revdel);
		$('#imageres-temprm').click(tempmodify);
	});
});

// </nowiki>