<commit_before>Promise = require 'bluebird'
needle = Promise.promisifyAll(require 'needle')
cheerio = require 'cheerio'
_ = require 'lodash'
Bottleneck = require 'bottleneck'

Errors = require './errors'
Validation = require './provider/validation'

needle.defaults({
  follow_max: 10
})

class SearchResult
  constructor: (object) ->
    {@seriesName, @seriesUrl, @searchProvider, @episodes = [], @isSpecial = false} = object

class Episode
  constructor: (object) ->
    {@number, @title, @url, @searchProvider} = object

class Scraper
  constructor: ->
    @providers = {}
    @limiter = new Bottleneck(0, 500)

  use: (provider) ->
    return new Promise (resolve, reject) =>
      try
        if Validation.Logic.ValidateProvider(provider)
          @providers[provider.name] = provider
          return resolve(provider.initialize())
      catch error
        reject(error)

  search: (name, provider) ->
    @fetchSearchResult(name, @providers[provider])

  searchAll: (name) ->
    Promise.map Object.keys(@providers), (provider) =>
      @fetchSearchResult(name, @providers[provider])

  fetchSearchResult: (query, provider) ->
    @limiter.schedule(provider.methods.search, query).then (body) ->
      $ = cheerio.load(body)

      provider.methods.list($, body).then (list) ->

        list = list.map (i, el) ->
          return new SearchResult({
            seriesName: provider.search.row.name($(el))
            seriesUrl: provider.search.row.url($(el))
            searchProvider: provider.name
          })
        .get()

        list = _.filter list, (item) ->
          return item.seriesName.toUpperCase().indexOf(query.toUpperCase()) > -1

  fetchSeries: (searchResult) ->
    provider = @providers[searchResult.searchProvider]
    needle.getAsync(searchResult.seriesUrl, provider.http_options).then (resp) =>
      $ = cheerio.load(resp.body)

      episodes = provider.methods.seriesList($, resp.body).then (episodes) ->
        console.log episodes
        episodes = episodes.map (i, el) ->
          if !provider.series.row.number?
            number = i+1
          else
            number = provider.series.row.number($(el))
          return new Episode({
            title: provider.series.row.name($(el))
            url: provider.series.row.url($(el))
            number: number
            searchProvider: provider.name
          })
        .get()

        searchResult.episodes = episodes
        return searchResult

  fetchVideo: (episode) ->
    provider = @providers[episode.searchProvider]
    needle.getAsync(episode.url, provider.http_options).then (resp) =>
      $ = cheerio.load(resp.body)
      provider.methods.episode($, resp.body)

module.exports = Scraper<commit_msg>Removed debugging code<commit_after>Promise = require 'bluebird'
needle = Promise.promisifyAll(require 'needle')
cheerio = require 'cheerio'
_ = require 'lodash'
Bottleneck = require 'bottleneck'

Errors = require './errors'
Validation = require './provider/validation'

needle.defaults({
  follow_max: 10
})

class SearchResult
  constructor: (object) ->
    {@seriesName, @seriesUrl, @searchProvider, @episodes = [], @isSpecial = false} = object

class Episode
  constructor: (object) ->
    {@number, @title, @url, @searchProvider} = object

class Scraper
  constructor: ->
    @providers = {}
    @limiter = new Bottleneck(0, 500)

  use: (provider) ->
    return new Promise (resolve, reject) =>
      try
        if Validation.Logic.ValidateProvider(provider)
          @providers[provider.name] = provider
          return resolve(provider.initialize())
      catch error
        reject(error)

  search: (name, provider) ->
    @fetchSearchResult(name, @providers[provider])

  searchAll: (name) ->
    Promise.map Object.keys(@providers), (provider) =>
      @fetchSearchResult(name, @providers[provider])

  fetchSearchResult: (query, provider) ->
    @limiter.schedule(provider.methods.search, query).then (body) ->
      $ = cheerio.load(body)

      provider.methods.list($, body).then (list) ->

        list = list.map (i, el) ->
          return new SearchResult({
            seriesName: provider.search.row.name($(el))
            seriesUrl: provider.search.row.url($(el))
            searchProvider: provider.name
          })
        .get()

        list = _.filter list, (item) ->
          return item.seriesName.toUpperCase().indexOf(query.toUpperCase()) > -1

  fetchSeries: (searchResult) ->
    provider = @providers[searchResult.searchProvider]
    needle.getAsync(searchResult.seriesUrl, provider.http_options).then (resp) =>
      $ = cheerio.load(resp.body)

      episodes = provider.methods.seriesList($, resp.body).then (episodes) ->
        episodes = episodes.map (i, el) ->
          if !provider.series.row.number?
            number = i+1
          else
            number = provider.series.row.number($(el))
          return new Episode({
            title: provider.series.row.name($(el))
            url: provider.series.row.url($(el))
            number: number
            searchProvider: provider.name
          })
        .get()

        searchResult.episodes = episodes
        return searchResult

  fetchVideo: (episode) ->
    provider = @providers[episode.searchProvider]
    needle.getAsync(episode.url, provider.http_options).then (resp) =>
      $ = cheerio.load(resp.body)
      provider.methods.episode($, resp.body)

module.exports = Scraper
{'fraction_non_alphanumeric': 0.13428149242704102, 'fraction_numerical': 0.0029553010712966383, 'mean_word_length': 2.75, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7173519', 'n_tokens_mistral': 1621, 'n_tokens_neox': 1585, 'n_words': 327}