From 8df8696c665e8f2ca25d26d77afc969503d73cdb Mon Sep 17 00:00:00 2001 From: Harmjan Kors Date: Thu, 5 Jan 2017 21:34:59 +0100 Subject: [PATCH] Parse actual information using Node.js --- nodejs/README.md | 23 +++ nodejs/index.js | 484 ++++++++++++++++++++++++++++++++++++++++++++ nodejs/package.json | 16 ++ 3 files changed, 523 insertions(+) create mode 100644 nodejs/README.md create mode 100644 nodejs/index.js create mode 100644 nodejs/package.json diff --git a/nodejs/README.md b/nodejs/README.md new file mode 100644 index 0000000..cee4281 --- /dev/null +++ b/nodejs/README.md @@ -0,0 +1,23 @@ +# SocialClub parser +## Install Node.js +Download Node.js from http://www.nodejs.org/ + +## Install node dependencies +``` +npm install +``` +By running the above CLI command from the folder containing the ```package.json``` file, a folder ```node_modules``` will be created with all the dependencies defined in ```package.json```. This folder contains modules that are necessary to run the script. + +## Modify credentials +Your SocialClub username and password need to be given at the first two lines of the ```index.js``` file. + +## Run the script +``` +node . +``` +The above CLI command will execute the ```index.js``` file and prints the user information of the user belonging to the username configured in the ```index.js``` file. + +``` +node . +``` +This CLI command executes the ```index.js``` file and prints the user information of the user belonging to the username specified in the command. \ No newline at end of file diff --git a/nodejs/index.js b/nodejs/index.js new file mode 100644 index 0000000..44437f1 --- /dev/null +++ b/nodejs/index.js @@ -0,0 +1,484 @@ +var USERNAME = 'YOUR_SOCIALCLUB_USERNAME'; +var PASSWORD = 'YOUR_SOCIALCLUB_PASSWORD'; + +var DEFAULT_HEADERS = { + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'en-US,en;q=0.8,nl;q=0.6', + 'Connection': 'keep-alive', + 'Host': 'socialclub.rockstargames.com', + 'Origin': 'https://socialclub.rockstargames.com', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36' +}; + +var async = require('async'); +var cheerio = require('cheerio'); +var fs = require('fs'); +var request = require('request'); +var FileCookieStore = require('tough-cookie-filestore'); + +/* -------------------------------------- */ + +/** + * Start the script. + */ +function start(forceNewLogin) { + + // Force a new login to SocialClub, for example when the cookies are not valid anymore + if (forceNewLogin) { + renewAuthentication(function (cookieJar, verificationToken) { + printActualInformation(cookieJar); + }); + return; + } + + console.log('Checking for existing cookies and verification token'); + + async.parallel({ + getCookiesFile: function (done) { + readFile('cookies.json', function (err, cookieFileData) { + done(err, cookieFileData); + }); + }, + getVerificationTokenFile: function (done) { + readFile('verificationToken.txt', function (err, verificationFileData) { + done(err, verificationFileData); + }); + } + }, function (err, results) { + if (err) { + console.error(err); + return; + } + + var cookieFileData = results['getCookiesFile']; + var verificationToken = results['getVerificationTokenFile']; + + // If one or both files doesn't exist, renew the authentication + if (!cookieFileData || !verificationToken) { + console.log('No existing cookies and/or verification token found'); + + start(true); + return; + } + + console.log('Existing cookies and verification token found'); + + try { + + // Use the existing cookies and verification token + var cookieJar = request.jar(new FileCookieStore('cookies.json')); + printActualInformation(cookieJar); + } catch (err) { + + // Sometimes an exception is thrown because the cookies.json file contains invalid JSON for some reason + if (err instanceof SyntaxError) { + console.log('Existing cookies are unreadable'); + + // So renew the authentication in that case + start(true); + } else { + console.error(err); + } + } + }); +} + +/** + * Get the contents of a file. If it doesn't exist, an empty string is given to the callback. + * @param {string} filePath - The file path of the file to be read. + * @param {function} callback - Function that gets called when the contents of the verification token file is retrieved. + */ +function readFile(filePath, callback) { + fs.readFile(filePath, 'utf8', function (err, data) { + if (err && err.code === 'ENOENT') { + callback(''); + return; + } + + callback(err, data); + }); +} + +/** + * Get the current timestamp. + * @returns {number} - The current timestamp. + */ +function getTimestamp() { + return Math.floor(new Date().getTime()); +} + +/** + * Parse a string to an integer, including stripping the 'per mille' sign (,) and the dollar sign ($). + * @param {string} input - The input to be parsed to an integer. + * @returns {number} - The parsed integer. + */ +function parseInteger(input) { + return parseInt(input.replace(/[\$,]/g, '').trim()); +} + +/* -------------------------------------- */ + +/** + * Function to sign into SocialClub to get a "AuthenticateCookie" cookie. + * @param {function} callback - Function that gets called when the authentication is renewed. + */ +function renewAuthentication(callback) { + console.log('Renewing the authentication'); + + createCookiesJar(function (cookieJar) { + getVerificationToken(cookieJar, function (cookieJar, verificationToken) { + signIn(cookieJar, verificationToken, function (cookieJar) { + callback(cookieJar, verificationToken); + }); + }); + }); +} + +/** + * Creates a new cookie jar. + * @param callback - Function that gets called when the cookie jar is created. + */ +function createCookiesJar(callback) { + + // Create the cookies jar file + fs.writeFile('cookies.json', '', function (err) { + if (err) { + console.error(err); + return; + } + + // Create an empty cookie jar, which will be filled with cookies + var cookieJar = request.jar(new FileCookieStore('cookies.json')); + + callback(cookieJar); + }); +} + +/** + * Remember a SocialClub verification token. It is saved to a .txt file. + * @param {string} verificationToken - The SocialClub verification token to be remembered. + * @param callback - Function that gets called when the verification token is saved. + */ +function rememberVerificationToken(verificationToken, callback) { + fs.writeFile('verificationToken.txt', verificationToken, function (err) { + if (err) { + console.error(err); + return; + } + + callback(); + }); +} + +/** + * Function to retrieve the login page of SocialClub to get a verification token. + * @param {RequestJar} cookieJar - An (empty) cookie jar. + * @param {function} callback - Function that gets called when the verification token is retrieved. + */ +function getVerificationToken(cookieJar, callback) { + var options = { + gzip: true, + headers: DEFAULT_HEADERS, + jar: cookieJar, + url: 'https://socialclub.rockstargames.com/profile/signin' + }; + + console.log('Send GET-request to: ' + options.url); + request.get(options, function (err, response, body) { + if (err) { + console.error(err); + return; + } + + // Caution: There are multiple "__RequestVerificationToken" in the body, take the right one + var regExpVerificationToken = new RegExp('[^]*