diff --git a/README.md b/README.md index cb59b79..822c4a4 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,23 @@ Easy way to search for porn content ## Simple search +You can do it in two ways: + ```js -const pornsearch = require('pornsearch'); -const pornhub = pornsearch.load('pornhub'); +const Pornsearch = require('pornsearch'); +const Searcher = new Pornsearch('tits'); + +Searcher.videos() + .then(videos => console.log(videos)); +``` -pornhub.videos('boobs') - .then(response => console.log(response)); +or (my favourite) -pornhub.gifs('pov') - .then(response => console.log(response)); +```js +const Pornsearch = require('pornsearch').search('ass'); + +Pornsearch.gifs() + .then(gifs => console.log(gifs)); ``` ## Support @@ -49,99 +57,89 @@ What will return in gif search ## Installation -Via GIT: -```bash -$ git clone git://github.com/LucasLeandro1204/api.git node_modules/pornsearch -``` Via NPM: ```bash $ npm install pornsearch ``` -## Output - -#### Videos -If has success, the return will be an array with videos, structured as -```js -{ - title: 'video title', - url: 'video url', - duration: 'video duration', - thumb: 'video thumbnail' -} -``` -If has error, will be returned a message like -```Markdown -No results for search related to *relation* in page *page* and category number *number* +Via GIT: +```bash +$ git clone git://github.com/LucasLeandro1204/api.git node_modules/pornsearch ``` -**Check the support table to know exactly what will be returned** - -#### Gifs +## Usage -If has success, the return will be an array with gifs, structured as +There's two ways to use Pornsearch: -__PORNHUB gifs in general are extremely heavy, so be a nice person and share webm__ (sex.com gifs are nice) +You can create a new instance with two parameters: the first one is the query, what you want to search, the second one is the driver (Pornhub default). ```js -{ - title: 'gif title', - url: 'gif url', - webm: 'gif webm url' -} +const Pornsearch = require('pornsearch'); +const Searcher = new Pornsearch(query, driver = 'pornhub'); ``` -If has error, will be returned a message like -```Markdown -No results for search related to *relation* in page *page* -``` - -**Check the support table to know exactly what will be returned** -## Usage +Or you can use the static search method, but you can pass only the query, the driver will be pornhub. +```js +const Pornsearch = require('pornsearch').search(query); +``` -First require Pornsearch +But you always can change the current driver: ```js -const pornsearch = require('pornsearch'); +Pornsearch.driver(driver); ``` -Then pass the website you want to search on (like 'pornhub') + +**An error will be thrown if Pornsearch don't support the driver you passed in** + +To know the current driver ```js -const pornhub = pornsearch.load('pornhub'); +Pornsearch.current(); ``` -**Check the [support table](#support) to know what you can do** -**An error will be thrown if don't support** -Search for related only +## Search + +It's easy to search for porn content with Pornsearch =) + +**Check the [support table](#support) to know what you can do** ```js -pornhub.videos('boobs') - .then((response) => { - console.log(response); - }) - .catch((error) => { - console.log(error); - }); - -pornhub.gifs('pussy') - .then((response) => { - console.log(response); - }) - .catch((error) => { - console.log(error); - }); +Pornsearch.videos() + .then(videos => console.log(videos) + .then(() => Pornsearch.gifs()) + .then(gifs => console.log(gifs)); ``` -Specify the page number to search on +Specify the page to search on ```js -pornhub.videos('ass', 3); +Pornsearch.gifs(3); +``` -pornhub.gifs('teta', 7); +Change de query +```js +Pornsearch.search('pussy') + .gifs(gifs => console.log(gifs)); ``` Log only url ```js -pornhub.gifs('teen') - .then((gifs) => { - console.log(gifs.map(gif => gif.url)); - }); +Pornsearch.gifs(3) + .then(gifs => console.log(gifs.map(gif => gif.url))); ``` + +## Output + +#### Videos + +To know what the current driver will return in video search check the [videos structure](#videos-structure) + +#### Gifs + +To know what the current driver will return in gif search check the [gifs structure](#gifs-structure) + +__PORNHUB gifs in general are extremely heavy, so be a nice person and share webm__ (sex.com gifs are nice) + +If has error in whenever search, will be throw an error: +```Markdown +No results for search related to *query* in page *page* +``` + diff --git a/example/example.js b/example/example.js index 9f9d235..2ed3f81 100644 --- a/example/example.js +++ b/example/example.js @@ -1,12 +1,11 @@ 'use strict'; -const pornsearch = require('../'); -const pornhub = pornsearch.load('pornhub'); +const Pornsearch = require('../').search(); -pornhub.videos('boobs') - .then((response) => { - console.log(response); +Pornsearch.driver('sex').gifs() + .then((gifs) => { + console.log(gifs); + + return Pornsearch.videos(); }) - .catch((error) => { - console.log(error); - }); \ No newline at end of file + .then(videos => console.log(videos)); diff --git a/index.js b/index.js index 8e857ca..f54c141 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,3 @@ 'use strict'; -module.exports = require('./src/pornsearch'); \ No newline at end of file +module.exports = require('./src/Pornsearch'); diff --git a/package.json b/package.json index f54aa24..060fc28 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pornsearch", "version": "1.2.3", - "description": "Easy way to search for porn content on Pornhub", + "description": "Easy way to search for porn content on internet", "main": "src/pornsearch.js", "scripts": { "test": "node ./example/example" diff --git a/src/Core/AbstractModule.js b/src/Core/AbstractModule.js new file mode 100644 index 0000000..b5ffd5d --- /dev/null +++ b/src/Core/AbstractModule.js @@ -0,0 +1,41 @@ +'use strict'; + +class AbstractModule { + constructor () { + this.query = ''; + } + + get name () { + throw new Error('This function must be overwrite'); + } + + get firstpage () { + throw new Error('This function must be overwrite'); + } + + videoUrl () { + throw new Error(`${this.name} doesn't support video search`); + } + + gifUrl () { + throw new Error(`${this.name} doesn't support gif search`); + } + + videoParser () { + throw new Error('This function must be overwrite'); + } + + gifParser () { + throw new Error('This function must be overwrite'); + } + + static extendsToMe (module) { + if (! (module instanceof this)) { + throw new Error(`Module should be an instance of Abstract module`); + } + + return module; + } +}; + +module.exports = AbstractModule; diff --git a/src/Modules/Pornhub.js b/src/Modules/Pornhub.js new file mode 100644 index 0000000..55a8560 --- /dev/null +++ b/src/Modules/Pornhub.js @@ -0,0 +1,58 @@ +'use strict'; + +const AbstractModule = require('../Core/AbstractModule'); + +class Pornhub extends AbstractModule { + get name () { + return 'Pornhub'; + } + + get firstpage () { + return 1; + } + + videoUrl (page) { + return `http://www.pornhub.com/video/search?search=${this.query}&page=${page || this.firstpage}`; + } + + gifUrl (page) { + return `http://www.pornhub.com/gifs/search?search=${this.query}&page=${page || this.firstpage}`; + } + + videoParser ($) { + let videos = $('ul.videos.search-video-thumbs li'); + + return videos.map((i, video) => { + video = $(video); + + let data = video.find('a').eq(0); + + return data.length + ? { + title: data.find('img').attr('title'), + url: 'http://pornhub.com/' + data.attr('href'), + duration: data.find('.duration').text(), + thumb: data.find('img').attr('data-mediumthumb').replace('(m=ecuK8daaaa)', '') + } + : undefined; + }).get(); + } + + gifParser ($) { + let gifs = $('ul.gifs.gifLink li'); + + return gifs.map((i, gif) => { + gif = $(gif); + + let data = gif.find('a'); + + return { + title: data.find('span').text(), + url: 'http://dl.phncdn.com#id#.gif'.replace('#id#', data.attr('href')), + webm: data.find('video').attr('data-webm') + }; + }).get(); + } +}; + +module.exports = Pornhub; diff --git a/src/Modules/Redtube.js b/src/Modules/Redtube.js new file mode 100644 index 0000000..a1bf224 --- /dev/null +++ b/src/Modules/Redtube.js @@ -0,0 +1,30 @@ +'use strict'; + +const AbstractModule = require('../Core/AbstractModule'); + +class Redtube extends AbstractModule { + get name () { + return 'Redtube'; + } + + get firstpage () { + return 1; + } + + videoUrl (page) { + return `https://api.redtube.com/?data=redtube.Videos.searchVideos&output=json&search=${this.query}&thumbsize=big&page=${page || this.firstpage}`; + } + + videoParser ($, { videos }) { + return videos.map(({ video }) => { + return { + title: video.title, + url: video.url, + duration: video.duration, + thumb: video.default_thumb, + }; + }); + } +}; + +module.exports = Redtube; diff --git a/src/Modules/Sex.js b/src/Modules/Sex.js new file mode 100644 index 0000000..7459886 --- /dev/null +++ b/src/Modules/Sex.js @@ -0,0 +1,55 @@ +'use strict'; + +const AbstractModule = require('../Core/AbstractModule'); + +class Sex extends AbstractModule { + get name () { + return 'Sex'; + } + + get firstpage () { + return 1; + } + + videoUrl (page) { + return `http://www.sex.com/search/videos?query=${this.query}&page=${page || this.firstpage}`; + } + + gifUrl (page) { + return `http://www.sex.com/search/gifs?query=${this.query}&page=${page || this.firstpage}`; + } + + videoParser ($) { + let videos = $('#masonry_container .masonry_box').has('.duration'); + + return videos.map((i, video) => { + video = $(video); + + let title = video.find('.title a'); + + return { + title: title.text(), + url: 'http://www.sex.com' + title.attr('href'), + duration: video.find('.duration').text(), + thumb: video.find('.image').data('src') + }; + }).get(); + } + + gifParser ($) { + let gifs = $('#masonry_container .masonry_box').not('.ad_box'); + + return gifs.map((i, gif) => { + gif = $(gif); + + let data = gif.find('.image'); + + return { + title: data.attr('alt'), + url: data.data('src') + } + }).get(); + } +}; + +module.exports = Sex; diff --git a/src/Modules/Xvideos.js b/src/Modules/Xvideos.js new file mode 100644 index 0000000..0ec8e7e --- /dev/null +++ b/src/Modules/Xvideos.js @@ -0,0 +1,35 @@ +'use strict'; + +const AbstractModule = require('../Core/AbstractModule'); + +class Xvideos extends AbstractModule { + get name () { + return 'xVideos'; + } + + get firstpage () { + return 0; + } + + videoUrl (page) { + return `https://www.xvideos.com/?k=${this.query}&p=${page || this.firstpage}`; + } + + videoParser ($) { + let videos = $('#content .mozaique .thumb-block'); + + return videos.map((i, video) => { + video = $.load($(video).find('.thumb script').text().match(/(<.*>)/).pop()); + let description = video.find('p'); + + return { + title: description.eq(0).text(), + url: 'https://xvideos.com' + $('a').attr('href'), + duration: description.find('strong').text(), + thumb: $('img').attr('src') + }; + }).get(); + } +}; + +module.exports = Xvideos; diff --git a/src/Pornsearch.js b/src/Pornsearch.js new file mode 100644 index 0000000..49107b2 --- /dev/null +++ b/src/Pornsearch.js @@ -0,0 +1,92 @@ +'use strict'; + +const AbstractModule = require('./Core/AbstractModule'); +const Axios = require('axios'); +const Cheerio = require('cheerio'); +const FS = require('fs'); +const Path = require('path'); + +const GIF = 'gif'; +const PARSER = 'Parser'; +const VIDEO = 'video'; + +class Pornsearch { + constructor (query, driver = 'pornhub') { + this.module = {}; + this.modules = []; + + this.load() + .driver(driver) + .search(query); + } + + support () { + return this.modules.map(module => module.name); + } + + current () { + return this.module.name; + } + + get query () { + return this.module.query || ''; + } + + search (query) { + if (Object.keys(this.module).length != 0) { + this.module.query = query; + } + + return this; + } + + gifs (page) { + return this._get(this.module.gifUrl(page), GIF); + } + + videos (page) { + return this._get(this.module.videoUrl(page), VIDEO, page || this.module.firstpage); + } + + _get (url, type, page) { + return new Promise((resolve, reject) => { + Axios.get(url) + .then(({ data: body }) => { + resolve(this.module[type + PARSER](Cheerio.load(body), body)); + }) + .catch((error) => { + console.log(error); + reject(`No results for search related to ${this.module.query} in page ${page}`); + }); + }); + } + + driver (driver = '') { + let currentQuery = this.query; + let module = this.modules.find(module => module.name.toLowerCase() == driver.toLowerCase()); + + if (! module) { + throw new Error(`We don't support ${driver} by now =/`); + } + + this.module = module; + this.module.query = currentQuery; + + return this; + } + + load () { + let dir = Path.resolve('./src/Modules'); + let files = FS.readdirSync(dir, 'UTF-8'); + + this.modules = files.map(file => AbstractModule.extendsToMe(new (require(Path.resolve(dir, file))))); + + return this; + } + + static search (query) { + return new this(query); + } +}; + +module.exports = Pornsearch; diff --git a/src/modules/pornhub.js b/src/modules/pornhub.js deleted file mode 100644 index 08fc619..0000000 --- a/src/modules/pornhub.js +++ /dev/null @@ -1,81 +0,0 @@ -'use strict'; - -const axios = require('axios'); -const cheerio = require('cheerio'); - -const Pornhub = { - - videos(relation, page = 1) { - let url = `http://www.pornhub.com/video/search?search=${relation}&page=${page}`; - - return new Promise((resolve, reject) => { - axios.get(url) - .then((response) => { - resolve(this.video.parse(response.data)); - }) - .catch((error) => { - console.log(error); - reject(`No results for search related to ${relation} in page ${page}`); - }); - }); - }, - - gifs(relation, page = 1) { - let url = `http://www.pornhub.com/gifs/search?search=${relation}&page=${page}`; - - return new Promise((resolve, reject) => { - axios.get(url) - .then((response) => { - resolve(this.gif.parse(response.data)); - }) - .catch((error) => { - reject(`No results for search related to ${relation} in page ${page}`); - }); - }); - }, - - video: { - parse(body) { - const $ = cheerio.load(body); - let videos = $('ul.videos.search-video-thumbs li'); - - return videos.map((i, video) => this.format($(video))).get(); - }, - - format(video) { - let data = video.find('a').eq(0); - - if (data.length !== 1) { - return undefined; - } - - return { - title: data.find('img').attr('title'), - url: 'http://pornhub.com/' + data.attr('href'), - duration: data.find('.duration').text(), - thumb: data.find('img').attr('data-mediumthumb').replace('(m=ecuK8daaaa)', '') - }; - } - }, - - gif: { - parse(body) { - const $ = cheerio.load(body); - let gifs = $('ul.gifs.gifLink li'); - - return gifs.map((i, gif) => this.format($(gif))).get(); - }, - - format(gif) { - let data = gif.find('a'); - - return { - title: data.find('span').text(), - url: 'http://dl.phncdn.com#id#.gif'.replace('#id#', data.attr('href')), - webm: data.find('video').attr('data-webm') - }; - } - } -}; - -module.exports = Pornhub; \ No newline at end of file diff --git a/src/modules/redtube.js b/src/modules/redtube.js deleted file mode 100644 index 07ec1a3..0000000 --- a/src/modules/redtube.js +++ /dev/null @@ -1,38 +0,0 @@ -'use strict'; - -const axios = require('axios'); - -const Redtube = { - - videos(relation, page = 1) { - let url = `https://api.redtube.com/?data=redtube.Videos.searchVideos&output=json&search=${relation}&thumbsize=big&page=${page}`; - - return new Promise((resolve, reject) => { - axios.get(url) - .then((response) => { - resolve(this.video.format(response.data.videos)); - }) - .catch((error) => { - console.log(error); - reject(`No results for search related to ${relation} in page ${page}`); - }); - }); - }, - - video: { - format(videos) { - return videos.map((data) => { - let video = data.video; - - return { - title: video.title, - url: video.url, - duration: video.duration, - thumb: video.default_thumb, - }; - }); - } - } -}; - -module.exports = Redtube; \ No newline at end of file diff --git a/src/modules/sex.js b/src/modules/sex.js deleted file mode 100644 index 271fa17..0000000 --- a/src/modules/sex.js +++ /dev/null @@ -1,76 +0,0 @@ -'use strict'; - -const axios = require('axios'); -const cheerio = require('cheerio'); - -const Sex = { - - videos(relation, page = 1) { - let url = `http://www.sex.com/search/videos?query=${relation}&page=${page}`; - - return new Promise((resolve, reject) => { - axios.get(url) - .then((response) => { - resolve(this.video.parse(response.data)); - }) - .catch((error) => { - console.log(error); - reject(`No results for search related to ${relation} in page ${page}`); - }); - }); - }, - - gifs(relation, page = 1) { - let url = `http://www.sex.com/search/gifs?query=${relation}&page=${page}`; - - return new Promise((resolve, reject) => { - axios.get(url) - .then((response) => { - resolve(this.gif.parse(response.data)); - }) - .catch((error) => { - reject(`No results for search related to ${relation} in page ${page}`); - }); - }); - }, - - video: { - parse(body) { - const $ = cheerio.load(body); - let videos = $('#masonry_container .masonry_box').has('.duration'); - - return videos.map((i, video) => this.format($(video))).get(); - }, - - format(video) { - let title = video.find('.title a'); - - return { - title: title.text(), - url: 'http://www.sex.com' + title.attr('href'), - duration: video.find('.duration').text(), - thumb: video.find('.image').data('src') - }; - } - }, - - gif: { - parse(body) { - const $ = cheerio.load(body); - let gifs = $('#masonry_container .masonry_box').not('.ad_box'); - - return gifs.map((i, gif) => this.format($(gif))).get(); - }, - - format(gif) { - let data = gif.find('.image'); - - return { - title: data.attr('alt'), - url: data.data('src') - } - } - } -} - -module.exports = Sex; diff --git a/src/modules/xvideos.js b/src/modules/xvideos.js deleted file mode 100644 index 8f2a311..0000000 --- a/src/modules/xvideos.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict'; - -const axios = require('axios'); -const cheerio = require('cheerio'); - -const xVideos = { - - videos(relation, page = 0) { - let url = `https://www.xvideos.com/?k=${relation}&p=${page}`; - - return new Promise((resolve, reject) => { - axios.get(url) - .then((response) => { - resolve(this.video.parse(response.data)); - }) - .catch((error) => { - console.log(error); - reject(`No results for search related to ${relation} in page ${page}`); - }); - }); - }, - - video: { - parse(body) { - const $ = cheerio.load(body); - let videos = $('#content .mozaique .thumb-block'); - - return videos.map((i, video) => this.format($(video))).get(); - }, - - format(video) { - let $ = cheerio.load(video.find('.thumb script').text().match(/(<.*>)/)[0]); - let description = video.find('p'); - - return { - title: description.eq(0).text(), - url: 'https://xvideos.com' + $('a').attr('href'), - duration: description.find('strong').text(), - thumb: $('img').attr('src') - }; - } - } -}; - -module.exports = xVideos; \ No newline at end of file diff --git a/src/pornsearch.js b/src/pornsearch.js deleted file mode 100644 index 1c03cfd..0000000 --- a/src/pornsearch.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; - -const Pornsearch = { - - load(site) { - try { - return require(`./modules/${site}`); - } catch(error) { - throw new Error(`Currently we do not support ${site}`); - } - } -}; - -module.exports = Pornsearch; \ No newline at end of file