Greasy Fork is available in English.

MyAnimeList (MAL) Tags Updater

Adds type, genres and other info to entries tags. Can also delete all current tags.

11.04.2015 itibariyledir. En son verisyonu görün.

// ==UserScript==
// @name         MyAnimeList (MAL) Tags Updater
// @namespace    https://greasyfork.org/users/7517
// @description  Adds type, genres and other info to entries tags. Can also delete all current tags.
// @version      2.1.0
// @author       akarin
// @include      /^http\:\/\/myanimelist\.net\/(anime|manga)list/
// @include      /^http\:\/\/myanimelist\.net\/panel\.php\?go=(add|edit)/
// @include      /^http\:\/\/myanimelist\.net\/editlist\.php\?type=(anime|manga)&id=/
// @grant        none
// ==/UserScript==

;(function() {  
	const GET_DELAY = 300
	const ANIME_T = 'anime'
	const MANGA_T = 'manga'
	
	var ADD_EDIT = false
	var LIST_TYPE
	
	if (document.URL.match(/\/(anime|manga)list\//)) {	
		// exit if this is another user's list
		if ($('#mal_cs_otherlinks div:first strong').text().match(/^You are viewing your/) === null) {
			return
		}
		
		// exit if the tags column is hidden
		if ($('#list_surround td[class^=td][width="125"]').length === 0) {
			return
		}
		
		LIST_TYPE = document.URL.match('/animelist/') ? ANIME_T : MANGA_T
				
		$('#mal_cs_otherlinks div:last').append($('<span>&nbsp;&nbsp;|&nbsp;&nbsp;</span>')
			.append($('<a href="javascript:void(0)">Update Tags</a>').click(function() { 
				if (true === confirm('Are you sure you want to update all tags?')) {
					updateAllTags(false)
				}
			}))
			.append('&nbsp;&nbsp;')
			.append($('<a href="javascript:void(0)">Clear Tags</a>').click(function() { 
				if (true === confirm('Are you sure you want to clear all tags?')) {
					updateAllTags(true)
				}
			}))
		)
		
		$('#list_surround div[id^=tagChangeRow] a').each(function() {
			var id = $(this).attr('onclick').match(/Edit\((\d+),/)[1]
			$(this).replaceWith(
				$('<a href="javascript:void(0)"></a>').click(function() { 
					updateTags(id, false)
				})
				.append('<small>upd</small>')
			)
		})	
	}
	else {
		ADD_EDIT = true
		LIST_TYPE = document.URL.match(/(\?go=(add|edit)&|\?type=anime&)/) ? ANIME_T : MANGA_T
		
		var id = $('strong + a:contains(Info)').prop('href').match(/\d+/)[0]
		$('td.borderClass:contains(Tags)').append(
			$('<a href="javascript:void(0)"></a>').click(function() { 
				updateTags(id, false)
			})
			.append('&nbsp;<small>update</small>')
		)
	}
	
	const TAGS_LINK = '/includes/ajax.inc.php?' + (LIST_TYPE === ANIME_T ? 't=22&aid=' : 't=30&mid=')

	function updateAllTags(clear) {
		$('span[id^=tagLinks]').each(function(index) {
			if (clear === false || $(this).children().length) {
				var id = $(this)[0].id.match(/\d+/)[0]
				setTimeout(function() { updateTags(id, clear) }, GET_DELAY * index)
			}
		})
	}
	
	function updateTags(id, clear) {
		if (clear === true) {
			setTags(id, '')
			return
		}		
		$.get('/' + LIST_TYPE + '/' + id + '/_/pics', function(data) {				
			setTags(id, LIST_TYPE === ANIME_T ? getAnimeTags(data) : getMangaTags(data))
		})
	}
	
	function setTags(id, tags) {
		if (ADD_EDIT === true) {
			$('#tagtext').prop('value', tags.replace(/, /g, ',').replace(/,$/, '').replace(/,/g, ', '))
			return
		}
		tags = tags.replace(/'/g, '')
		$.get(TAGS_LINK + id + '&tags=' + tags, function(data) {
			$('#tagLinks' + id).html(data)
			$('#tagRow' + id).text($(data).text())
		})
	}	
	
	function getAnimeTags(html) {
		const M = {	
			TYPE: 1, STATUS: 2,	AIRED: 3, PRODUCERS: 4, GENRES: 5, RATING: 6 
		}		
		var tags = html.match(/<h2>Information<\/h2>[\s\S]*?>Type:<\/span>([\s\S]*?)<\/div>[\s\S]*?>Status:<\/span>([\s\S]*?)<\/div>[\s\S]*?>Aired:<\/span>([\s\S]*?)<\/div>[\s\S]*?>Producers:<\/span>([\s\S]*?)<\/div>[\s\S]*?>Genres:<\/span>([\s\S]*?)<\/div>[\s\S]*?>Rating:<\/span>([\s\S]*?)( -|None)/)
		
		var date = getDate(tags[M.AIRED])

		return tags === null ? '' : $.map([
			tags[M.TYPE]
			,$(tags[M.GENRES]).text()
			,$(tags[M.PRODUCERS]
				.replace(/None found, <a href="\/dbchanges\.php\?(.*)>add some<\/a>\./, '')
				.replace(/<sup>[\s\S]*?<\/sup>/g, '')
				.replace(/,/g, '')
				.replace(/<\/a>[\s]*?<a/g, '</a>, <a')
			).text()
			,date.year
			,date.season
			//,tags[M.RATING] 
			//,tags[M.STATUS].replace('Finished Airing', 'Finished').replace('Currently Airing', 'Airing')		
		], $.trim).join(',')
	}
	
	function getMangaTags(html) {
		const M = {	
			TYPE: 1, STATUS: 2,	PUBLISHED: 3, GENRES: 4, AUTHORS: 5, SERIALIZATION: 6 
		}
		var tags = html.match(/<h2>Information<\/h2>[\s\S]*?>Type:<\/span>([\s\S]*?)<\/div>[\s\S]*?>Status:<\/span>([\s\S]*?)<\/div>[\s\S]*?>Published:<\/span>([\s\S]*?)<\/div>[\s\S]*?>Genres:<\/span>([\s\S]*?)<\/div>[\s\S]*?>Authors:<\/span>([\s\S]*?)<\/div>[\s\S]*?>Serialization:<\/span>([\s\S]*?)(None<\/div>|<\/div>)/)
		
		var date = getDate(tags[M.PUBLISHED])
		
		return tags === null ? '' : $.map([
			tags[M.TYPE]
			,$(tags[M.GENRES]).text()
			,$(tags[M.AUTHORS]
				.replace(/,/g, '')
				.replace(/\((Art|Story|Story & Art)\)/g, '')
				.replace(/<\/a>[\s]*?<a/g, '</a>, <a')
			).text()
			,$(tags[M.SERIALIZATION]).text()
			,date.year
			//,date.season
			//,tags[M.STATUS]		
		], $.trim).join(',')
	}
	
	function getDate(str) {
		var date = str.replace(/to(.*)$/, '').trim()
		var m_year = date.match(/[\d]{4}/)
		var months = {'Jan':1,'Feb':2,'Mar':3,'Apr':4,'May':5,'Jun':6,'Jul':7,'Aug':8,'Sep':9,'Oct':10,'Nov':11,'Dec':12}
		var m_month = date.match(/^[a-zA-Z]{3}/)
		var month = m_month !== null ? months[m_month[0]] : -1
		
		var result = {
			year: '', season: ''
		}
		
		if (m_year !== null) {
			result.year = m_year[0]
		}
		else {
			return result
		}
		
		if (month > 0) {
			if (month >= 1 && month <= 3) result.season = 'Winter'
			if (month >= 4 && month <= 6) result.season = 'Spring'
			if (month >= 7 && month <= 9) result.season = 'Summer'
			if (month >= 10 && month <= 12) result.season = 'Fall'
		}
		
		if (result.season.length > 0) {
			result.season += ' ' + result.year
		}
		
		return result
	}
})()