Skip to content

Instantly share code, notes, and snippets.

@brunoti
Created July 13, 2019 21:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brunoti/198a38f7a61155ebcb4264d1952b9d77 to your computer and use it in GitHub Desktop.
Save brunoti/198a38f7a61155ebcb4264d1952b9d77 to your computer and use it in GitHub Desktop.
my anime tosho hack
const Maybe = folktale.maybe
const Result = folktale.result
const noop = () => {}
const { href: current } = document.location
const { compose, ifElse, any, curry, split, head, map, complement, allPass, is, chain, find, mapObjIndexed, type } = R
const stringIncludes = curry((neddles, haystack) => any(neddles, n => haystack.includes(n)))
const findByClass = className => Array.from(document.getElementsByClassName(className))
const safeContextQuery = curry((query, el) => Maybe.fromNullable(el.querySelector(query)))
const safeContextQueryMany = curry((query, el) => Array.from(el.querySelectorAll(query)))
const safeFindById = id => Maybe.fromNullable(document.getElementById(id))
const isSeriesPage = (url) => url.includes('/series')
const query = '?filter%5B0%5D%5Bt%5D=nyaa_class&filter%5B0%5D%5Bv%5D=trusted&order='
const animes = [
{
name: 'Vinland Saga',
link: 'https://animetosho.org/series/vinland-saga.13945',
},
{
name: 'Fruits Basket',
link: 'https://animetosho.org/series/fruits-basket-1st-season.14490',
},
{
name: 'Carole & Tuesday',
link: 'https://animetosho.org/series/carole-tuesday.13893',
},
{
name: 'Dr. Stone',
link: 'https://animetosho.org/series/dr-stone.14491',
},
{
name: 'Fire Force',
link: 'https://animetosho.org/series/enen-no-shouboutai.14488',
},
]
const safeFunction = ifElse(is(Function), Result.Ok, e => Result.Error(type(e)))
const maker = curry((makerMap, mappable) => mapObjIndexed(
(maybeF, key) => maybeF.matchWith({
Ok: ({ value: f }) => f(mappable),
Error: ({ value: type }) => {
throw new TypeError(`Your value on prop "${key}" should be a function instead we got "${type}"`)
},
}),
map(safeFunction, makerMap)
))
const isNotNaN = complement(Number.isNaN)
const isMagnetEl = el => el.innerText === 'Magnet'
const safeNumber = ifElse(allPass([is(Number), isNotNaN]), Maybe.Just, Maybe.Nothing)
const parseSize = compose(map(Number), Maybe.fromNullable, head, split(' '))
const findText = compose(map(el => el.innerText), safeContextQuery('.link > a'))
const findMagnet = compose(map(el => el.href), Maybe.fromNullable, find(isMagnetEl), safeContextQueryMany('.links > a'))
const findSize = compose(chain(parseSize), map(e => e.innerText), safeContextQuery('.size'))
const isHighQuality = stringIncludes(['780p', '1080p'])
const makeLinkObject = maker({
text: findText,
size: findSize,
magnet: findMagnet,
})
const trace = prefix => item => {
console.log(prefix, item)
return item
}
const addAnimeToSideBar = (anime) => {
const where = safeFindById('topbar_tagline')
where.matchWith({
Nothing: () => console.error('Element not found'),
Just: ({ value: el }) => {
const link = document.createElement('a')
link.href = anime.link + query
link.innerText = anime.name
link.className = 'anime-link'
el.parentNode.insertBefore(link, el.nextSibling)
},
})
}
animes.forEach(addAnimeToSideBar)
if (isSeriesPage(current)) {
const html = `
<div class="link-list">
${findByClass('home_list_entry').map(makeLinkObject).map(anime => (`
<a href=${anime.magnet.getOrElse('NOT FOUND')} class="link-list__item">
${anime.text.getOrElse('NOT FOUND')} - ${anime.size.getOrElse('NOT FOUND')}
</a>
`)).join('')}
</div>
`
document.body.insertAdjacentHTML('beforeend', html)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment