Skip to content

Commit

Permalink
feat(eztv-api): Added possibility for multiple shows to be in one id
Browse files Browse the repository at this point in the history
This will add the second show and format the episodes correctly for that one.
This is in case EZTV maps episode / shows incorrectly
  • Loading branch information
TriPSs committed Oct 19, 2021
1 parent 8ca4e1f commit 0772ad3
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 119 deletions.
243 changes: 134 additions & 109 deletions packages/eztv-api/src/eztv-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import bytes from 'bytes'
import { name } from '../package.json'
import slugMap from './slug-map'
import imdbMap from './imdb-map'
import formatMap from './format-map'
import { Show, ShowWithEpisodes } from './interfaces'

/**
Expand All @@ -23,18 +24,6 @@ export class EztvApi {

private debug = debug(name)

/**
* Maps the EZTV imdb codes to trakt.tv imdb codes.
* @type {Object}
*/
public static readonly slugMap = slugMap

/**
* Maps the EZTV slugs to trakt.tv slugs.
* @type {Object}
*/
public static readonly imdbMap = imdbMap

/**
* Create a new instance of the module.
* @param {!Object} config={} - The configuration object for the module.
Expand All @@ -56,9 +45,10 @@ export class EztvApi {

this.debug(`Making request to: '${uri}'`)

return got.get(uri).then(({ body }) => {
return cheerio.load(body)
})
return got.get(uri)
.then(({ body }) => {
return cheerio.load(body)
})
}

/**
Expand All @@ -70,129 +60,164 @@ export class EztvApi {
.attr('href')

imdb = imdb ? imdb.match(/\/title\/(.*)\//)[1] : undefined
imdb = imdb in EztvApi.imdbMap ? EztvApi.imdbMap[imdb] : imdb
imdb = imdb in imdbMap ? imdbMap[imdb] : imdb

if (imdb) {
data.imdb = imdb
}

const table = 'tr.forum_header_border[name="hover"]'
$(table).each(function () {
const entry = $(this)
const magnet = entry.children('td').eq(2)
.children('a.magnet')
.first()
.attr('href')

if (!magnet) {
return
}
$(table)
.each(function() {
const entry = $(this)
const magnet = entry.children('td')
.eq(2)
.children('a.magnet')
.first()
.attr('href')

const seasonBased = /S?0*(\d+)[xE]0*(\d+)/i
const dateBased = /(\d{4}).(\d{2}.\d{2})/i
const title = entry.children('td').eq(1)
.text()
.replace('x264', '')
let season
let episode

if (title.match(seasonBased)) {
season = parseInt(title.match(seasonBased)[1], 10)
episode = parseInt(title.match(seasonBased)[2], 10)
data.dateBased = false

} else if (title.match(dateBased)) {
// If a item becomes data based check if the name of the show is in the
// item this prevents wrongly mapped items to be added
if (!data.dateBased && !title.toLowerCase().includes(data.title.toLowerCase())) {
if (!magnet) {
return
}

season = title.match(dateBased)[1]
episode = title.match(dateBased)[2].replace(/\s/g, '-')
data.dateBased = true
} else {
season = null
episode = null
}

if (season !== null && episode !== null) {
if (!data.torrents) {
data.torrents = {}
const seasonBased = /S?0*(\d+)[xE]0*(\d+)/i
const dateBased = /(\d{4}).(\d{2}.\d{2})/i
const title = entry.children('td')
.eq(1)
.text()
.replace('x264', '')
let season
let episode

if (title.match(seasonBased)) {
season = parseInt(title.match(seasonBased)[1], 10)
episode = parseInt(title.match(seasonBased)[2], 10)
data.dateBased = false

} else if (title.match(dateBased)) {
// If a item becomes data based check if the name of the show is in the
// item this prevents wrongly mapped items to be added
if (!data.dateBased && !title.toLowerCase()
.includes(data.title.toLowerCase())) {
return
}

season = title.match(dateBased)[1]
episode = title.match(dateBased)[2].replace(/\s/g, '-')
data.dateBased = true
} else {
season = null
episode = null
}

if (!data.torrents[season]) {
data.torrents[season] = {}
if (season !== null && episode !== null) {
if (!data.torrents) {
data.torrents = {}
}

if (!data.torrents[season]) {
data.torrents[season] = {}
}

if (!data.torrents[season][episode]) {
data.torrents[season][episode] = []
}

const quality = title.match(/(\d{3,4})p/)
? title.match(/(\d{3,4})p/)[0]
: '480p'

const seeds = parseInt(
entry.children('td')
.last()
.text(),
10
)

const sizeText = entry.children('td')
.eq(3)
.text()
.toUpperCase()

const size = bytes(sizeText.trim())

data.torrents[season][episode].push({
title,
url: magnet,
seeds: isNaN(seeds) ? 0 : seeds,
peers: 0,
provider: 'EZTV',
size: isNaN(size) ? 0 : size,
quality
})
}

if (!data.torrents[season][episode]) {
data.torrents[season][episode] = []
}

const quality = title.match(/(\d{3,4})p/)
? title.match(/(\d{3,4})p/)[0]
: '480p'

const seeds = parseInt(
entry.children('td').last()
.text(),
10
)

const sizeText = entry.children('td').eq(3)
.text().toUpperCase()

const size = bytes(sizeText.trim())

data.torrents[season][episode].push({
title,
url: magnet,
seeds: isNaN(seeds) ? 0 : seeds,
peers: 0,
provider: 'EZTV',
size: isNaN(size) ? 0 : size,
quality
})
}
})
})

return data
}

/**
* Get all the available shows from eztv.
*/
public getAllShows(): Promise<Show[]> {
return this.get('showlist/').then(($) => {
const regex = /\/shows\/(.*)\/(.*)\//

return $('.thread_link').map(function () {
const entry = $(this)
const href = entry.attr('href')

const title = entry.text()
const id = parseInt(href.match(regex)[1], 10)

let slug = href.match(regex)[2]
slug = slug in EztvApi.slugMap ? EztvApi.slugMap[slug] : slug

return {
title,
id,
slug
}
}).get()
public async getAllShows(): Promise<Show[]> {
const shows = await this.get('showlist/')
.then(($) => {
const regex = /\/shows\/(.*)\/(.*)\//

return $('.thread_link')
.map(function() {
const entry = $(this)
const href = entry.attr('href')

const title = entry.text()
const id = parseInt(href.match(regex)[1], 10)

let slug = href.match(regex)[2]
slug = slug in slugMap ? slugMap[slug] : slug

return {
title,
id,
slug
}
})
.get()
})

// Loop through all shows to see if they have a additional show in it
shows.forEach((show) => {
if (show.slug in formatMap) {
shows.push(formatMap[show.slug].additionalShow)
}
})

return shows
}

/**
* Get episodes for a show.
* @param {Show} data - Teh show to get episodes for.
* @returns {Promise<Show, Error>} - The show with additional data.
*/
public getShowData(data: Show) {
return this.get(`shows/${data.id}/${data.slug}/`)
public async getShowData(data: Show): Promise<ShowWithEpisodes> {
let showId = data.id
let showSlug = data.slug

// Check if the slug is in the format map, if so get the original id and slug
if (data.slug in formatMap) {
showId = formatMap[showSlug].id
showSlug = formatMap[showSlug].slug
}

const showData = await this.get(`shows/${showId}/${showSlug}/`)
.then(($) => this.getEpisodeData(data, $))

// If the slug is inside the format map and has formatShow then return the formatted show
if (data.slug in formatMap && formatMap[data.slug].formatShow) {
return formatMap[showData.slug].formatShow(showData)
}

return showData
}

}
53 changes: 53 additions & 0 deletions packages/eztv-api/src/format-map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { ShowWithEpisodes, Torrent } from './interfaces'

const addTorrentToShow = (show: ShowWithEpisodes, season: string, episode: string, torrent: Torrent) => {
if (!show.torrents[season]) {
show.torrents[season] = {}
}

if (!show.torrents[season][episode]) {
show.torrents[season][episode] = []
}

show.torrents[season][episode].push(torrent)

return show
}

export default {
'what-if-2021': {
id: 6179,
slug: 'what-if',
formatShow: (show: ShowWithEpisodes): ShowWithEpisodes => {
const marvelsWhatIfShow = {
...show,
id: 0,
slug: 'what-if-2021',
imdb: 'tt10168312',
torrents: {}
}

Object.keys(show.torrents)
.forEach((season) => {
Object.keys(show.torrents[season])
.forEach((episode) => {
show.torrents[season][episode].forEach((torrent: Torrent) => {
if (torrent.title.includes('What If')) {
addTorrentToShow(marvelsWhatIfShow, season, episode, torrent)
}
})
})
})

return marvelsWhatIfShow
}
},

'what-if': {
additionalShow: {
id: 0,
slug: 'what-if-2021',
title: 'What If...'
}
}
}
4 changes: 4 additions & 0 deletions packages/eztv-api/src/imdb-map.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* Maps the EZTV slugs to trakt.tv slugs.
* @type {Object}
*/
export default {
tt0093036: 'tt3074694',
tt0102517: 'tt1657505',
Expand Down
22 changes: 12 additions & 10 deletions packages/eztv-api/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,23 @@ export interface Show {

}

export interface Torrent {
title: string
url: string
seeds: number
peers: 0,
provider: string
size: number
quality: string
}

export interface ShowWithEpisodes extends Show {

imdb: string

episodes: {
torrents: {
[season: number]: {
[episode: number]: [{
title: string
url: string
seeds: number
peers: 0,
provider: string
size: number
quality: string
}]
[episode: number]: Torrent[]
}
}

Expand Down
Loading

0 comments on commit 0772ad3

Please sign in to comment.