Skip to content

Commit

Permalink
Introduce Session + Page classes and rename Browser into Scraper
Browse files Browse the repository at this point in the history
  • Loading branch information
zzarcon committed Mar 27, 2019
1 parent 4698958 commit afe3e88
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 157 deletions.
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8.5.0
2 changes: 1 addition & 1 deletion example/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const run = async () => {
throw new Error('No username or password')
}

const bot = new LuckyBot(user, pass, {debug: true});
const bot = new LuckyBot(user, pass);

console.log('LOGIN...')
await bot.login();
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"build:es2015": "tsc --project build/tsconfig.es2015.json",
"build": "rm -rf dist && yarn build:es5 && yarn build:es2015",
"build:example": "rm -rf example/dist && tsc --project build/tsconfig.example.json",
"typecheck": "tsc --noEmit --project tsconfig.json",
"test": "jest"
},
"dependencies": {
Expand All @@ -24,6 +25,9 @@
"ts-node-dev": "^1.0.0-pre.32",
"typescript": "^3.3.4000"
},
"engines": {
"node": ">=8.5.0"
},
"repository": "[email protected]:devlucky/luckybot.git",
"author": "devlucky",
"license": "MIT",
Expand Down
148 changes: 0 additions & 148 deletions src/browser.ts

This file was deleted.

2 changes: 2 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const HOST = 'https://www.instagram.com';
export const DEBUG = process.env.NODE_ENV !== 'production'
16 changes: 8 additions & 8 deletions src/luckybot.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Browser } from "./browser";
import { Scraper } from "./strategies/scraper";

export interface BotOptions {
debug?: boolean;
Expand All @@ -11,24 +11,24 @@ export interface LikeOptions {
export class LuckyBot {
userName: string;
password: string;
browser: Browser;
scraper: Scraper;

constructor(userName: string, password: string, options?: BotOptions) {
constructor(userName: string, password: string) {
this.userName = userName;
this.password = password;
this.browser = new Browser(options);
this.scraper = new Scraper();
}

async login(): Promise<void> {
const {browser, userName, password} = this;
await browser.login(userName, password);
const {scraper, userName, password} = this;
await scraper.login(userName, password);
}

async likePhotos(hashtag: string, options: LikeOptions = {maxLikes: 50}) {
await this.browser.likePhotos(hashtag, options);
await this.scraper.likePhotos(hashtag, options);
}

async close() {
await this.browser.close();
await this.scraper.close();
}
}
38 changes: 38 additions & 0 deletions src/page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import puppeteer, { Browser } from 'puppeteer';
import { Page } from "puppeteer";
import { DEBUG } from './config';

export class PageProvider {
// those need to be static since we don't want to have multiple pages at the same time
static page?: Page;
static browser?: Browser;

private async createPage() {
const browser = await puppeteer.launch({ headless: !DEBUG });
const page = await browser.newPage();
const userAgent = await browser.userAgent();

await page.setViewport({width: 1024, height: 768});
await page.setUserAgent(userAgent.replace('Headless', ''));

PageProvider.browser = browser;
PageProvider.page = page;

return page;
}

getPage(): Promise<Page> {
const {page} = PageProvider;

if (page) return Promise.resolve(page);

return this.createPage();
}

async close() {
const {page, browser} = PageProvider;

page && await page.close()
browser && await browser.close()
}
}
42 changes: 42 additions & 0 deletions src/session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Page, Cookie } from "puppeteer";
import { HOST } from "./config";
import { PageProvider } from "./page";

export class Session {
isLoggedIn: boolean = false;
pageProvider: PageProvider;
page?: Page;

constructor() {
this.pageProvider = new PageProvider();
}

async login(userName: string, password: string): Promise<Cookie[]> {
const page = await this.pageProvider.getPage();

if (this.isLoggedIn) {
return page.cookies();
};

await page.goto(`${HOST}/accounts/login`);

const userInput = await page.waitForSelector('input._2hvTZ');
const passInput = await page.waitForSelector('input[type=password]');
const logInButton = await page.waitForSelector('button[type="submit"]');

if (!userInput || !passInput || !logInButton) {
throw new Error('Error loging');
}

await userInput.type(userName);
await passInput.type(password);
await logInButton.click()
await page.waitForNavigation();

const cookies = await page.cookies();

this.isLoggedIn = true;
return cookies;
}

}
5 changes: 5 additions & 0 deletions src/strategies/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// TODO: xhr call to private rest api goes here

export class RestApi {

}
Loading

0 comments on commit afe3e88

Please sign in to comment.