// ==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> | </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(' ')
.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(' <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
}
})()