From 85e1bddd5a6e40633bd4c2c7396e7890e8fe772e Mon Sep 17 00:00:00 2001 From: hansputera Date: Mon, 5 Jul 2021 02:00:31 +0000 Subject: [PATCH 1/7] testing --- dist/src/main.js | 8 ++- dist/src/types.d.ts | 100 +++++++++++++++++++++++++++++++++++ dist/src/types.js | 2 + src/main.ts | 12 +++-- src/tests/index.test.ts | 4 +- src/{types.d.ts => types.ts} | 0 tsconfig.json | 9 +++- 7 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 dist/src/types.d.ts create mode 100644 dist/src/types.js rename src/{types.d.ts => types.ts} (100%) diff --git a/dist/src/main.js b/dist/src/main.js index 8a676b0..29455f0 100644 --- a/dist/src/main.js +++ b/dist/src/main.js @@ -13,7 +13,13 @@ class Brainly { clientRequest = (lang) => got_1.default.extend({ prefixUrl: `${this.getBaseURL(lang)}/graphql`, headers: { - "user-agent": this.getAgent() + "user-agent": this.getAgent(), + "origin": this.getBaseURL(lang), + "sec-gpc": "1", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin", + "batch": "true" } }); /** diff --git a/dist/src/types.d.ts b/dist/src/types.d.ts new file mode 100644 index 0000000..9bc5d19 --- /dev/null +++ b/dist/src/types.d.ts @@ -0,0 +1,100 @@ +export declare type LanguageList = "id" | "us" | "es" | "ru" | "ro" | "pt" | "tr" | "ph" | "pl" | "hi"; +export declare type BaseURLObject = Record; +export declare type Attachments = string[]; +export interface Question { + id: number; + content: string; + author?: Author; + attachments: Attachments; + url: string; + created: string; + points: { + points: number; + forBest: number; + }; + grade: string; + education: string; + can_be_answered: boolean; +} +export interface Author { + id: number; + url: string; + username: string; + avatar_url?: string; + deleted: boolean; + rank: string; + description: string; + gender: string; + points: number; + receivedThanks: number; + bestAnswersCount: number; + helpedUsersCount: number; +} +export interface Answer { + content: string; + attachments: Attachments; + rates: number; + rating: number; + author?: Author; + isBest: boolean; + created: string; +} +export interface BrainlyResponse { + highlight: { + contentFragments: string[]; + }; + node: { + id: string; + created: string; + databaseId: number; + content: string; + points: number; + pointsForBestAnswer: number; + author: { + avatar: { + url: string; + } | null; + databaseId: number; + id: string; + isDeleted: boolean; + nick: string; + rank: { + name: string; + }; + description: string; + points: number; + receivedThanks: number; + bestAnswersCount: number; + helpedUsersCount: number; + gender: string; + }; + canBeAnswered: boolean; + grade: { + name: string; + slug: string; + }; + subject: { + name: string; + slug: string; + }; + answers: { + hasVerified: boolean; + nodes: { + ratesCount: number; + rating: number; + thanksCount: number; + content: string; + attachments: { + url: string; + }[]; + author: BrainlyResponse["node"]["author"]; + isBest: boolean; + points: number; + created: string; + }[]; + }; + attachments: { + url: string; + }[]; + }; +} diff --git a/dist/src/types.js b/dist/src/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/dist/src/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/src/main.ts b/src/main.ts index 5970e1e..f0af09b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,7 +9,13 @@ export default class Brainly { public clientRequest = (lang: LanguageList) => Got.extend({ prefixUrl: `${this.getBaseURL(lang)}/graphql`, headers: { - "user-agent": this.getAgent() as string + "user-agent": this.getAgent() as string, + "origin": this.getBaseURL(lang), + "sec-gpc": "1", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin", + "batch": "true" } }); @@ -45,7 +51,7 @@ export default class Brainly { avatar_url: obj.node.author.avatar ? obj.node.author.avatar!.url : undefined, deleted: obj.node.author.isDeleted, url: `${this.getBaseURL(language)}/app/profile/${obj.node.author.databaseId}`, - rank: obj.node.author.rank.name, + rank: obj.node.author.rank ? obj.node.author.rank.name : "-", username: obj.node.author.nick, receivedThanks: obj.node.author.receivedThanks, bestAnswersCount: obj.node.author.bestAnswersCount, @@ -84,7 +90,7 @@ export default class Brainly { points: answerObj.author.points, helpedUsersCount: answerObj.author.helpedUsersCount, receivedThanks: answerObj.author.receivedThanks, - rank: answerObj.author.rank.name + rank: answerObj.author.rank ? answerObj.author.rank.name : "-" } : undefined })); diff --git a/src/tests/index.test.ts b/src/tests/index.test.ts index 6543c76..6695c74 100644 --- a/src/tests/index.test.ts +++ b/src/tests/index.test.ts @@ -1,8 +1,8 @@ import Brainly from "../../index"; it("should return information about question and answer", (done) => { - const brain = new Brainly("id"); - brain.search("ru", "Pythagoras").then((results) => { + const brain = new Brainly("us"); + brain.search("us", "Pythagoras").then((results) => { console.log(results[0].question) expect(results).toBeDefined(); done(); diff --git a/src/types.d.ts b/src/types.ts similarity index 100% rename from src/types.d.ts rename to src/types.ts diff --git a/tsconfig.json b/tsconfig.json index 70765e8..bbc1343 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,8 +8,13 @@ "declaration": true, "esModuleInterop": true, "pretty": true, - "skipLibCheck": true + "skipLibCheck": true, + "typeRoots": [ + "./node_modules/@types", + "./src/types" + ], + "baseUrl": "./src", }, "exclude": ["node_modules"], - "include": ["src/**/*", "tests/**/*"] + "include": ["src/**/*.ts", "tests/**/*"] } \ No newline at end of file From e3a7cc2425fc5a223700173360aee244568cd3d5 Mon Sep 17 00:00:00 2001 From: hansputera Date: Mon, 5 Jul 2021 02:35:27 +0000 Subject: [PATCH 2/7] remove united states region code --- AVAILABLE_LANGUAGES.md | 2 +- README.md | 11 +++- package.json | 1 + src/main.ts | 136 +++++++++++++++++++++------------------- src/tests/index.test.ts | 2 +- src/types.ts | 6 +- tsconfig.json | 4 +- 7 files changed, 88 insertions(+), 74 deletions(-) diff --git a/AVAILABLE_LANGUAGES.md b/AVAILABLE_LANGUAGES.md index bd85b91..83409fc 100644 --- a/AVAILABLE_LANGUAGES.md +++ b/AVAILABLE_LANGUAGES.md @@ -1,7 +1,7 @@ # Here is available language you can use in this library - Indonesia ~ If your hosting location or application location is in Indonesia, you can enter code `id` -- United States ~ If your hosting location or application location is in America or United States (US), you can enter code `us`. +- ~~United States ~ If your hosting location or application location is in America or United States (US), you can enter code `us`.~~ Removed. - Spain ~ If your hosting location or application location is in Spain, you can enter code `es`. - Portuguese ~ If your hosting location or application location is in Portuguese, you can enter code `pt`. - Russia ~ If your hosting location or application location is in Russia, you can enter code `ru`. diff --git a/README.md b/README.md index 5e1b776..cf97b4d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Brainly Scraper V2 This library retrieves data from Brainly that has been designed to avoid `403 Forbidden` exception. -> To avoid such errors, you can fill in a valid country code according to the location of your hosting server. For example, heroku, heroku with the United States region. That is, you must fill in the code `us` as the country code inside the brainly parameter constructor. +> To avoid such errors, you can fill in a valid country code. You can test the 10 languages or country codes available to see if your server hosting country location or location is rejected. -You can test the 10 languages or country codes available to see if your server hosting country location or location is rejected. See https://github.com/hansputera/brainly-scraper-languages/blob/master/AVAILABLE_LANGUAGES.md +See https://github.com/hansputera/brainly-scraper-languages/blob/master/AVAILABLE_LANGUAGES.md # 💉 Installation - Using NPM : `npm install brainly-scraper-v2` @@ -52,5 +52,12 @@ brain.search("es", "Pythagoras").then(console.log).catch(console.error); # ⚙️ Issues and Bugs If you have problems using this library, you can create an issue in the [github repository](https://github.com/hansputera/brainly-scraper-languages). Remember, don't forget to read the instructions and try. +# 🔬 Hosting testing +## Replit.com +Free and paid hosting replit already tested. The country codes that pass are Indonesia, Spain, India, Portuguese, and Philipines. + + +Ever tried and tested on other hosting? Please send us your feedback. That would be very helpful 😊. + # ✍️ Contributions Do you want to contribute with this library for the better? Very well, fork this [github repository](https://github.com/hansputera/brainly-scraper-languages) then install dependencies to your directory. Happy coding 😁 \ No newline at end of file diff --git a/package.json b/package.json index 31f6b54..3691697 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "2.0.2", "description": "A library that makes it easy to retrieve data from brainly sites.", "main": "dist/index.js", + "types": "dist/index.d.ts", "scripts": { "test": "jest", "start": "node ./dist", diff --git a/src/main.ts b/src/main.ts index f0af09b..54955d6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,13 +1,13 @@ import Got from "got"; import { baseURLs, graphql_query, languages } from "./config"; import BrainlyError from "./error"; -import type { Answer, BaseURLObject, BrainlyResponse, LanguageList, Question } from "./types"; +import type { Answer, BaseURLObject, BrainlyResponse, CountryList, LanguageList, Question } from "./types"; import RandomUserAgent from "random-useragent"; import Util from "./util"; export default class Brainly { public clientRequest = (lang: LanguageList) => Got.extend({ - prefixUrl: `${this.getBaseURL(lang)}/graphql`, + prefixUrl: `${this.getBaseURL(this.country)}/graphql`, headers: { "user-agent": this.getAgent() as string, "origin": this.getBaseURL(lang), @@ -21,9 +21,9 @@ export default class Brainly { /** * - * @param country - Here, please put your application server country code, if your server are in United States. Enter region/country code `us` to this parameter. Because what? All brainly website is protected, if you do not enter valid region/country code. It will trigger an Error Exception. + * @param country - Here, please put your application server country code. if you do not enter valid region/country code. It will trigger an Error Exception. */ - constructor(public country: LanguageList = "id") { + constructor(public country: CountryList = "id") { if (!this.isValidLanguage(country)) throw new BrainlyError("Please put valid country!"); } @@ -35,71 +35,75 @@ export default class Brainly { * @param length Length array from question list */ public async search(language: LanguageList = "id", question: string, length = 10) { - if (!this.isValidLanguage(language)) throw new BrainlyError("Please put valid language!"); - const body = this.getRequestBody(question, length); - const response = await this.clientRequest(this.country.toLowerCase() as LanguageList).post(language.toLowerCase(), { - json: body - }); - const validJSON = JSON.parse(response.body)[0].data.questionSearch.edges as BrainlyResponse[]; - const objects = validJSON.map(obj => { - const question: Question = { - id: obj.node.databaseId, - content: Util.clearContent(obj.node.content), - attachments: obj.node.attachments.map(attach => attach.url), - author: obj.node.author ? { - id: obj.node.author.databaseId, - avatar_url: obj.node.author.avatar ? obj.node.author.avatar!.url : undefined, - deleted: obj.node.author.isDeleted, - url: `${this.getBaseURL(language)}/app/profile/${obj.node.author.databaseId}`, - rank: obj.node.author.rank ? obj.node.author.rank.name : "-", - username: obj.node.author.nick, - receivedThanks: obj.node.author.receivedThanks, - bestAnswersCount: obj.node.author.bestAnswersCount, - gender: obj.node.author.gender, - description: obj.node.author.description, - points: obj.node.author.points, - helpedUsersCount: obj.node.author.helpedUsersCount - } : undefined, - points: { - points: obj.node.points, - forBest: obj.node.pointsForBestAnswer - }, - grade: obj.node.grade.name, - education: obj.node.subject.name, - created: obj.node.created, - can_be_answered: obj.node.canBeAnswered, - url: `${this.getBaseURL(language)}/${Util.resolveWorkName(language.toLowerCase() as LanguageList)}/${obj.node.databaseId}` - }; + try { + if (!this.isValidLanguage(language)) throw new BrainlyError("Please put valid language!"); + const body = this.getRequestBody(question, length); + const response = await this.clientRequest(this.country.toLowerCase() as LanguageList).post(language.toLowerCase(), { + json: body + }); + const validJSON = JSON.parse(response.body)[0].data.questionSearch.edges as BrainlyResponse[]; + const objects = validJSON.map(obj => { + const question: Question = { + id: obj.node.databaseId, + content: Util.clearContent(obj.node.content), + attachments: obj.node.attachments.map(attach => attach.url), + author: obj.node.author ? { + id: obj.node.author.databaseId, + avatar_url: obj.node.author.avatar ? obj.node.author.avatar!.url : undefined, + deleted: obj.node.author.isDeleted, + url: `${this.getBaseURL(language)}/app/profile/${obj.node.author.databaseId}`, + rank: obj.node.author.rank ? obj.node.author.rank.name : "-", + username: obj.node.author.nick, + receivedThanks: obj.node.author.receivedThanks, + bestAnswersCount: obj.node.author.bestAnswersCount, + gender: obj.node.author.gender, + description: obj.node.author.description, + points: obj.node.author.points, + helpedUsersCount: obj.node.author.helpedUsersCount + } : undefined, + points: { + points: obj.node.points, + forBest: obj.node.pointsForBestAnswer + }, + grade: obj.node.grade.name, + education: obj.node.subject.name, + created: obj.node.created, + can_be_answered: obj.node.canBeAnswered, + url: `${this.getBaseURL(language)}/${Util.resolveWorkName(language.toLowerCase() as LanguageList)}/${obj.node.databaseId}` + }; - const answers: Answer[] = obj.node.answers.nodes.map(answerObj => ({ - content: Util.clearContent(answerObj.content), - attachments: answerObj.attachments.map(attach => attach.url), - rates: answerObj.ratesCount, - rating: answerObj.rating, - isBest: answerObj.isBest, - created: answerObj.created, - author: answerObj.author ? { - id: answerObj.author.databaseId, - username: answerObj.author.nick, - gender: answerObj.author.gender, - avatar_url: answerObj.author.avatar ? answerObj.author.avatar.url : undefined, - deleted: answerObj.author.isDeleted, - url: `${this.getBaseURL(language.toLowerCase() as LanguageList)}/app/profile/${answerObj.author.databaseId}`, - description: answerObj.author.description, - bestAnswersCount: answerObj.author.bestAnswersCount, - points: answerObj.author.points, - helpedUsersCount: answerObj.author.helpedUsersCount, - receivedThanks: answerObj.author.receivedThanks, - rank: answerObj.author.rank ? answerObj.author.rank.name : "-" - } : undefined - })); + const answers: Answer[] = obj.node.answers.nodes.map(answerObj => ({ + content: Util.clearContent(answerObj.content), + attachments: answerObj.attachments.map(attach => attach.url), + rates: answerObj.ratesCount, + rating: answerObj.rating, + isBest: answerObj.isBest, + created: answerObj.created, + author: answerObj.author ? { + id: answerObj.author.databaseId, + username: answerObj.author.nick, + gender: answerObj.author.gender, + avatar_url: answerObj.author.avatar ? answerObj.author.avatar.url : undefined, + deleted: answerObj.author.isDeleted, + url: `${this.getBaseURL(language.toLowerCase() as LanguageList)}/app/profile/${answerObj.author.databaseId}`, + description: answerObj.author.description, + bestAnswersCount: answerObj.author.bestAnswersCount, + points: answerObj.author.points, + helpedUsersCount: answerObj.author.helpedUsersCount, + receivedThanks: answerObj.author.receivedThanks, + rank: answerObj.author.rank ? answerObj.author.rank.name : "-" + } : undefined + })); - return { - question, answers - } - }); + return { + question, answers + } + }); - return objects; + return objects; + } catch (err) { + throw new Error(JSON.stringify(err)); + } } private getRequestBody(question: string, length = 10) { diff --git a/src/tests/index.test.ts b/src/tests/index.test.ts index 6695c74..d2d9b58 100644 --- a/src/tests/index.test.ts +++ b/src/tests/index.test.ts @@ -1,7 +1,7 @@ import Brainly from "../../index"; it("should return information about question and answer", (done) => { - const brain = new Brainly("us"); + const brain = new Brainly("hi"); brain.search("us", "Pythagoras").then((results) => { console.log(results[0].question) expect(results).toBeDefined(); diff --git a/src/types.ts b/src/types.ts index e75626f..ea53628 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -export type LanguageList = "id" | "us" | "es" | "ru" | "ro" | "pt" | "tr" | "ph" | "pl" | "hi"; +export type CountryList = "id" | "es" | "ru" | "ro" | "pt" | "tr" | "ph" | "pl" | "hi"; export type BaseURLObject = Record; export type Attachments = string[]; @@ -97,4 +97,6 @@ export interface BrainlyResponse { } attachments: { url: string; }[]; } -} \ No newline at end of file +} + +export type LanguageList = CountryList | "us"; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index bbc1343..f93df69 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "allowJs": true, "strict": true, "outDir": "./dist", - "target": "ESNext", + "target": "ES2017", "module": "CommonJS", "declaration": true, "esModuleInterop": true, @@ -15,6 +15,6 @@ ], "baseUrl": "./src", }, - "exclude": ["node_modules"], + "exclude": ["node_modules", "dist"], "include": ["src/**/*.ts", "tests/**/*"] } \ No newline at end of file From 4fc1fb3a4c8e9a3977000178c3919748b3a65107 Mon Sep 17 00:00:00 2001 From: hansputera Date: Mon, 5 Jul 2021 02:37:18 +0000 Subject: [PATCH 3/7] readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf97b4d..2e1fe84 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ If you have problems using this library, you can create an issue in the [github Free and paid hosting replit already tested. The country codes that pass are Indonesia, Spain, India, Portuguese, and Philipines. -Ever tried and tested on other hosting? Please send us your feedback. That would be very helpful 😊. +Ever tried and tested on other hosting? Please send us your feedback in PR. That would be very helpful 😊. # ✍️ Contributions Do you want to contribute with this library for the better? Very well, fork this [github repository](https://github.com/hansputera/brainly-scraper-languages) then install dependencies to your directory. Happy coding 😁 \ No newline at end of file From cb4f3f9512c91e6f942d21e73e9cf1ccf7f90164 Mon Sep 17 00:00:00 2001 From: hansputera Date: Mon, 5 Jul 2021 02:38:42 +0000 Subject: [PATCH 4/7] remove us code from config --- src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.ts b/src/config.ts index 5684f94..37a13f6 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,7 +1,7 @@ export const graphql_query = "query SearchQuery($query: String!, $first: Int!, $after: ID) {\n questionSearch(query: $query, first: $first, after: $after) {\n count\n edges {\n node {\n databaseId\n content\n points\n created\n lastActivity\n subject {\n name\n slug\n }\n grade {\n name\n slug\n }\n attachments {\n url\n }\n author {\n databaseId\n nick\n points\n gender\n description\n isDeleted\n avatar {\n url\n }\n category\n clientType\n rank {\n databaseId\n name\n }\n receivedThanks\n bestAnswersCount\n helpedUsersCount\n }\n isAuthorsFirstQuestion\n canBeAnswered\n pointsForAnswer\n pointsForBestAnswer\n answers {\n nodes {\n databaseId\n content\n points\n isBest\n created\n rating\n ratesCount\n thanksCount\n attachments {\n url\n }\n author {\n databaseId\n nick\n points\n gender\n description\n isDeleted\n avatar {\n url\n }\n category\n clientType\n rank {\n databaseId\n name\n }\n receivedThanks\n bestAnswersCount\n helpedUsersCount\n }\n }\n }\n }\n }\n }\n }"; export const baseURLs = { id: "https://brainly.co.id", - us: "https://brainly.com", + //us: "https://brainly.com", es: "https://brainly.lat", pt: "https://brainly.com.br", ru: "https://znanija.com", From ac6c5a7d2985908fd124779aef149518324bfba7 Mon Sep 17 00:00:00 2001 From: hansputera Date: Mon, 5 Jul 2021 02:39:32 +0000 Subject: [PATCH 5/7] update build code --- dist/src/config.d.ts | 1 - dist/src/config.js | 2 +- dist/src/main.d.ts | 8 +- dist/src/main.js | 158 ++++++++++++++++++----------------- dist/src/tests/index.test.js | 4 +- dist/src/types.d.ts | 3 +- 6 files changed, 90 insertions(+), 86 deletions(-) diff --git a/dist/src/config.d.ts b/dist/src/config.d.ts index d9205e0..19526de 100644 --- a/dist/src/config.d.ts +++ b/dist/src/config.d.ts @@ -1,7 +1,6 @@ export declare const graphql_query = "query SearchQuery($query: String!, $first: Int!, $after: ID) {\n questionSearch(query: $query, first: $first, after: $after) {\n count\n edges {\n node {\n databaseId\n content\n points\n created\n lastActivity\n subject {\n name\n slug\n }\n grade {\n name\n slug\n }\n attachments {\n url\n }\n author {\n databaseId\n nick\n points\n gender\n description\n isDeleted\n avatar {\n url\n }\n category\n clientType\n rank {\n databaseId\n name\n }\n receivedThanks\n bestAnswersCount\n helpedUsersCount\n }\n isAuthorsFirstQuestion\n canBeAnswered\n pointsForAnswer\n pointsForBestAnswer\n answers {\n nodes {\n databaseId\n content\n points\n isBest\n created\n rating\n ratesCount\n thanksCount\n attachments {\n url\n }\n author {\n databaseId\n nick\n points\n gender\n description\n isDeleted\n avatar {\n url\n }\n category\n clientType\n rank {\n databaseId\n name\n }\n receivedThanks\n bestAnswersCount\n helpedUsersCount\n }\n }\n }\n }\n }\n }\n }"; export declare const baseURLs: { id: string; - us: string; es: string; pt: string; ru: string; diff --git a/dist/src/config.js b/dist/src/config.js index 17ccf2b..5f4775e 100644 --- a/dist/src/config.js +++ b/dist/src/config.js @@ -4,7 +4,7 @@ exports.languages = exports.baseURLs = exports.graphql_query = void 0; exports.graphql_query = "query SearchQuery($query: String!, $first: Int!, $after: ID) {\n questionSearch(query: $query, first: $first, after: $after) {\n count\n edges {\n node {\n databaseId\n content\n points\n created\n lastActivity\n subject {\n name\n slug\n }\n grade {\n name\n slug\n }\n attachments {\n url\n }\n author {\n databaseId\n nick\n points\n gender\n description\n isDeleted\n avatar {\n url\n }\n category\n clientType\n rank {\n databaseId\n name\n }\n receivedThanks\n bestAnswersCount\n helpedUsersCount\n }\n isAuthorsFirstQuestion\n canBeAnswered\n pointsForAnswer\n pointsForBestAnswer\n answers {\n nodes {\n databaseId\n content\n points\n isBest\n created\n rating\n ratesCount\n thanksCount\n attachments {\n url\n }\n author {\n databaseId\n nick\n points\n gender\n description\n isDeleted\n avatar {\n url\n }\n category\n clientType\n rank {\n databaseId\n name\n }\n receivedThanks\n bestAnswersCount\n helpedUsersCount\n }\n }\n }\n }\n }\n }\n }"; exports.baseURLs = { id: "https://brainly.co.id", - us: "https://brainly.com", + //us: "https://brainly.com", es: "https://brainly.lat", pt: "https://brainly.com.br", ru: "https://znanija.com", diff --git a/dist/src/main.d.ts b/dist/src/main.d.ts index 36eded6..4210917 100644 --- a/dist/src/main.d.ts +++ b/dist/src/main.d.ts @@ -1,12 +1,12 @@ -import type { Answer, LanguageList, Question } from "./types"; +import type { Answer, CountryList, LanguageList, Question } from "./types"; export default class Brainly { - country: LanguageList; + country: CountryList; clientRequest: (lang: LanguageList) => import("got").Got; /** * - * @param country - Here, please put your application server country code, if your server are in United States. Enter region/country code `us` to this parameter. Because what? All brainly website is protected, if you do not enter valid region/country code. It will trigger an Error Exception. + * @param country - Here, please put your application server country code. if you do not enter valid region/country code. It will trigger an Error Exception. */ - constructor(country?: LanguageList); + constructor(country?: CountryList); /** * Use this function if you want search question, it will returns question detail, question author, answer detail, attachments (if question or answer attachments is any), rating question and answer. * diff --git a/dist/src/main.js b/dist/src/main.js index 29455f0..f936582 100644 --- a/dist/src/main.js +++ b/dist/src/main.js @@ -9,25 +9,24 @@ const error_1 = __importDefault(require("./error")); const random_useragent_1 = __importDefault(require("random-useragent")); const util_1 = __importDefault(require("./util")); class Brainly { - country; - clientRequest = (lang) => got_1.default.extend({ - prefixUrl: `${this.getBaseURL(lang)}/graphql`, - headers: { - "user-agent": this.getAgent(), - "origin": this.getBaseURL(lang), - "sec-gpc": "1", - "sec-fetch-dest": "empty", - "sec-fetch-mode": "cors", - "sec-fetch-site": "same-origin", - "batch": "true" - } - }); /** * - * @param country - Here, please put your application server country code, if your server are in United States. Enter region/country code `us` to this parameter. Because what? All brainly website is protected, if you do not enter valid region/country code. It will trigger an Error Exception. + * @param country - Here, please put your application server country code. if you do not enter valid region/country code. It will trigger an Error Exception. */ constructor(country = "id") { this.country = country; + this.clientRequest = (lang) => got_1.default.extend({ + prefixUrl: `${this.getBaseURL(this.country)}/graphql`, + headers: { + "user-agent": this.getAgent(), + "origin": this.getBaseURL(lang), + "sec-gpc": "1", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-origin", + "batch": "true" + } + }); if (!this.isValidLanguage(country)) throw new error_1.default("Please put valid country!"); } @@ -39,69 +38,74 @@ class Brainly { * @param length Length array from question list */ async search(language = "id", question, length = 10) { - if (!this.isValidLanguage(language)) - throw new error_1.default("Please put valid language!"); - const body = this.getRequestBody(question, length); - const response = await this.clientRequest(this.country.toLowerCase()).post(language.toLowerCase(), { - json: body - }); - const validJSON = JSON.parse(response.body)[0].data.questionSearch.edges; - const objects = validJSON.map(obj => { - const question = { - id: obj.node.databaseId, - content: util_1.default.clearContent(obj.node.content), - attachments: obj.node.attachments.map(attach => attach.url), - author: obj.node.author ? { - id: obj.node.author.databaseId, - avatar_url: obj.node.author.avatar ? obj.node.author.avatar.url : undefined, - deleted: obj.node.author.isDeleted, - url: `${this.getBaseURL(language)}/app/profile/${obj.node.author.databaseId}`, - rank: obj.node.author.rank.name, - username: obj.node.author.nick, - receivedThanks: obj.node.author.receivedThanks, - bestAnswersCount: obj.node.author.bestAnswersCount, - gender: obj.node.author.gender, - description: obj.node.author.description, - points: obj.node.author.points, - helpedUsersCount: obj.node.author.helpedUsersCount - } : undefined, - points: { - points: obj.node.points, - forBest: obj.node.pointsForBestAnswer - }, - grade: obj.node.grade.name, - education: obj.node.subject.name, - created: obj.node.created, - can_be_answered: obj.node.canBeAnswered, - url: `${this.getBaseURL(language)}/${util_1.default.resolveWorkName(language.toLowerCase())}/${obj.node.databaseId}` - }; - const answers = obj.node.answers.nodes.map(answerObj => ({ - content: util_1.default.clearContent(answerObj.content), - attachments: answerObj.attachments.map(attach => attach.url), - rates: answerObj.ratesCount, - rating: answerObj.rating, - isBest: answerObj.isBest, - created: answerObj.created, - author: answerObj.author ? { - id: answerObj.author.databaseId, - username: answerObj.author.nick, - gender: answerObj.author.gender, - avatar_url: answerObj.author.avatar ? answerObj.author.avatar.url : undefined, - deleted: answerObj.author.isDeleted, - url: `${this.getBaseURL(language.toLowerCase())}/app/profile/${answerObj.author.databaseId}`, - description: answerObj.author.description, - bestAnswersCount: answerObj.author.bestAnswersCount, - points: answerObj.author.points, - helpedUsersCount: answerObj.author.helpedUsersCount, - receivedThanks: answerObj.author.receivedThanks, - rank: answerObj.author.rank.name - } : undefined - })); - return { - question, answers - }; - }); - return objects; + try { + if (!this.isValidLanguage(language)) + throw new error_1.default("Please put valid language!"); + const body = this.getRequestBody(question, length); + const response = await this.clientRequest(this.country.toLowerCase()).post(language.toLowerCase(), { + json: body + }); + const validJSON = JSON.parse(response.body)[0].data.questionSearch.edges; + const objects = validJSON.map(obj => { + const question = { + id: obj.node.databaseId, + content: util_1.default.clearContent(obj.node.content), + attachments: obj.node.attachments.map(attach => attach.url), + author: obj.node.author ? { + id: obj.node.author.databaseId, + avatar_url: obj.node.author.avatar ? obj.node.author.avatar.url : undefined, + deleted: obj.node.author.isDeleted, + url: `${this.getBaseURL(language)}/app/profile/${obj.node.author.databaseId}`, + rank: obj.node.author.rank ? obj.node.author.rank.name : "-", + username: obj.node.author.nick, + receivedThanks: obj.node.author.receivedThanks, + bestAnswersCount: obj.node.author.bestAnswersCount, + gender: obj.node.author.gender, + description: obj.node.author.description, + points: obj.node.author.points, + helpedUsersCount: obj.node.author.helpedUsersCount + } : undefined, + points: { + points: obj.node.points, + forBest: obj.node.pointsForBestAnswer + }, + grade: obj.node.grade.name, + education: obj.node.subject.name, + created: obj.node.created, + can_be_answered: obj.node.canBeAnswered, + url: `${this.getBaseURL(language)}/${util_1.default.resolveWorkName(language.toLowerCase())}/${obj.node.databaseId}` + }; + const answers = obj.node.answers.nodes.map(answerObj => ({ + content: util_1.default.clearContent(answerObj.content), + attachments: answerObj.attachments.map(attach => attach.url), + rates: answerObj.ratesCount, + rating: answerObj.rating, + isBest: answerObj.isBest, + created: answerObj.created, + author: answerObj.author ? { + id: answerObj.author.databaseId, + username: answerObj.author.nick, + gender: answerObj.author.gender, + avatar_url: answerObj.author.avatar ? answerObj.author.avatar.url : undefined, + deleted: answerObj.author.isDeleted, + url: `${this.getBaseURL(language.toLowerCase())}/app/profile/${answerObj.author.databaseId}`, + description: answerObj.author.description, + bestAnswersCount: answerObj.author.bestAnswersCount, + points: answerObj.author.points, + helpedUsersCount: answerObj.author.helpedUsersCount, + receivedThanks: answerObj.author.receivedThanks, + rank: answerObj.author.rank ? answerObj.author.rank.name : "-" + } : undefined + })); + return { + question, answers + }; + }); + return objects; + } + catch (err) { + throw new Error(JSON.stringify(err)); + } } getRequestBody(question, length = 10) { return [{ diff --git a/dist/src/tests/index.test.js b/dist/src/tests/index.test.js index cbb9793..dc15c81 100644 --- a/dist/src/tests/index.test.js +++ b/dist/src/tests/index.test.js @@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) { Object.defineProperty(exports, "__esModule", { value: true }); const index_1 = __importDefault(require("../../index")); it("should return information about question and answer", (done) => { - const brain = new index_1.default("id"); - brain.search("ru", "Pythagoras").then((results) => { + const brain = new index_1.default("hi"); + brain.search("us", "Pythagoras").then((results) => { console.log(results[0].question); expect(results).toBeDefined(); done(); diff --git a/dist/src/types.d.ts b/dist/src/types.d.ts index 9bc5d19..06a057d 100644 --- a/dist/src/types.d.ts +++ b/dist/src/types.d.ts @@ -1,4 +1,4 @@ -export declare type LanguageList = "id" | "us" | "es" | "ru" | "ro" | "pt" | "tr" | "ph" | "pl" | "hi"; +export declare type CountryList = "id" | "es" | "ru" | "ro" | "pt" | "tr" | "ph" | "pl" | "hi"; export declare type BaseURLObject = Record; export declare type Attachments = string[]; export interface Question { @@ -98,3 +98,4 @@ export interface BrainlyResponse { }[]; }; } +export declare type LanguageList = CountryList | "us"; From cf3a64d4de8c9da0487f4d8cebc50ea0822cca41 Mon Sep 17 00:00:00 2001 From: hansputera Date: Mon, 5 Jul 2021 02:44:06 +0000 Subject: [PATCH 6/7] fix typings --- .npmignore | 3 ++- package.json | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.npmignore b/.npmignore index 1ef2f33..9ec318d 100644 --- a/.npmignore +++ b/.npmignore @@ -1,2 +1,3 @@ .github -node_modules \ No newline at end of file +node_modules +src/ \ No newline at end of file diff --git a/package.json b/package.json index 3691697..55f8341 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,8 @@ { "name": "brainly-scraper-v2", - "version": "2.0.2", + "version": "2.0.3", "description": "A library that makes it easy to retrieve data from brainly sites.", "main": "dist/index.js", - "types": "dist/index.d.ts", "scripts": { "test": "jest", "start": "node ./dist", From 36924850df91b0e1b9224538d26b1a77d63bf03c Mon Sep 17 00:00:00 2001 From: hansputera Date: Mon, 5 Jul 2021 02:48:25 +0000 Subject: [PATCH 7/7] tired --- src/main.ts | 4 +++- tsconfig.json | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 54955d6..1412ae5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,8 +4,10 @@ import BrainlyError from "./error"; import type { Answer, BaseURLObject, BrainlyResponse, CountryList, LanguageList, Question } from "./types"; import RandomUserAgent from "random-useragent"; import Util from "./util"; +import { version } from "../package.json"; export default class Brainly { + public version = version; public clientRequest = (lang: LanguageList) => Got.extend({ prefixUrl: `${this.getBaseURL(this.country)}/graphql`, headers: { @@ -102,7 +104,7 @@ export default class Brainly { return objects; } catch (err) { - throw new Error(JSON.stringify(err)); + throw new BrainlyError(JSON.stringify(err)); } } diff --git a/tsconfig.json b/tsconfig.json index f93df69..5cf76b1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,6 +14,7 @@ "./src/types" ], "baseUrl": "./src", + "resolveJsonModule": true }, "exclude": ["node_modules", "dist"], "include": ["src/**/*.ts", "tests/**/*"]