intel-screenbot

An Ingress Intel Map Bot for Hangoutsbot
git clone git://archive.git.mtrnord.blog/MTRNord/intel-screenbot.git
Log | Files | Refs | README | LICENSE

commit bb4102798fd4d046fbc32e5c5d666cae3f3c33f6
parent 1d357588db71a999d9c2056593691a2544e2ee2f
Author: Marcel <MTRNord@users.noreply.github.com>
Date:   Sat, 19 Nov 2016 02:00:55 +0100

Merge pull request #2 from MTRNord/EmailLogin

Email login
Diffstat:
MREADME.md | 34+++++++++++++++++++++++++++++-----
MTODO.md | 6+++++-
M__init__.py | 96++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Mscreencap_iitc.js | 395+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Mscreencap_intel.js | 214+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
5 files changed, 616 insertions(+), 129 deletions(-)

diff --git a/README.md b/README.md @@ -6,7 +6,7 @@ Requires: **PhantomJS** (installation instructions below) Requires: **[hangoutsbot](https://github.com/hangoutsbot/hangoutsbot)** -Get and post a screenshot of the Intel Map. +Get and post a screenshot of the Intel Map. ## Install To install the plugin you need to: @@ -17,7 +17,9 @@ To install the plugin you need to: 4. Run `pip3 install -r requirements.txt` 5. Follow Configuration. -## Configuration +## Configuration with Cookies + +*Note Cookies do have to be changed on daily base* For using the Intel Screenbot you need to add the following to the config.json: ``` @@ -25,7 +27,29 @@ For using the Intel Screenbot you need to add the following to the config.json: "SACSID": "YOUR SACSID", "CSRF": "YOUR CSRF", "plugin_dirs": [ - "http://iitc.jonatkins.com/release/plugins" + "https://api.github.com/repos/iitc-project/iitc-project.github.io/git/trees/master?recursive=1" + ] + } +``` + +According to the official INSTALL Documention of the hangoutbot you will find the config.json in `/<username>/.local/share/hangupsbot/` +(NOTE! add an comma behind the last element of the config.json and add it befor the outer element closes) + +Also you need to add `intel_screenbot` to the plugins. + +## Configuration with Email Password + +**IMPORTANT: DO NOT USE YOUR MAIN ACCOUNT! I AM NOT RESPONSIBLE IF YOU ACCOUNT GETS BANNED! USE AT YOUR OWN RISK** + +*Note DON'T set cookies up when using emil/password* +For using the Intel Screenbot you need to add the following to the config.json: + +``` + "intel_screenbot": { + "email": "YOUR EMAIL", + "password": "YOUR Password", + "plugin_dirs": [ + "https://api.github.com/repos/iitc-project/iitc-project.github.io/git/trees/master?recursive=1" ] } ``` @@ -85,7 +109,7 @@ You should look at the Documentation of [ingress-ice](https://github.com/nibogd/ * Provide an arbitrary `<url>` to take a screenshot * If no `<url>` is supplied, use the default screenshot URL (or reply with an error if no URL is set) -## PhantomJS Installation +## PhantomJS Installation *May be outdated* @@ -95,7 +119,7 @@ You should look at the Documentation of [ingress-ice](https://github.com/nibogd/ ## Building PhantomJS from Source (Advanced) -Note: It is not within the scope of this project to discuss and resolve build problems with +Note: It is not within the scope of this project to discuss and resolve build problems with external libraries. **Install dependencies** diff --git a/TODO.md b/TODO.md @@ -1,5 +1,9 @@ # TODO -- Add `/bot iitc` +- Remove `/bot clear_iitcplugins` +- Add `/bot active_iitcplugins` +- Add zooming +- Add layer chooser +- Migrate intel command to iitc with default intel background layer - Add `/bot AP` - Add `/bot recharge` diff --git a/__init__.py b/__init__.py @@ -41,7 +41,7 @@ def _parse_onlineRepos(url, ext=''): for tree in value: for attribute, value in tree.items(): if attribute == "path": - if value.endswith(ext): + if value.endswith(ext) and not 'total-conversion-build.user.js' in value and not 'user-location.user.js' in value and not 'test' in value: files.append(url.replace("https://api.github.com/repos/", "https://raw.githubusercontent.com/").replace("git/trees/",'').replace("master?recursive=1","master/") + value) return files else: @@ -78,11 +78,10 @@ def _get_iitc_plugins(bot): else: bot.memory.set_by_path(["iitc_plugins"], iitc_plugins) -@asyncio.coroutine def _get_lines(shell_command): - p = yield from asyncio.create_subprocess_shell(shell_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - stdout, stderr = yield from p.communicate() - return p.returncode, stdout + p = yield from asyncio.create_subprocess_shell(shell_command) + output = yield from p.wait() + return p.returncode, output, True @asyncio.coroutine def _screencap(maptype, url, filepath, filename, SACSID, CSRF, plugins, search, bot, event): @@ -92,35 +91,38 @@ def _screencap(maptype, url, filepath, filename, SACSID, CSRF, plugins, search, if search == False: command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap_' + maptype + '.js "' + SACSID + '" "' + CSRF + '" "' + url + '" "' + filepath + '"' task = _get_lines(command) - task = asyncio.wait_for(task, 180.0, loop=self.loop) - exitcode, stdout = loop.run_until_complete(task) + task = asyncio.wait_for(task, 420.0) + exitcode, output, status = yield from task else: command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap_' + maptype + '.js "' + SACSID + '" "' + CSRF + '" "' + url + '" "' + filepath + '" "' + search + '"' task = _get_lines(command) - task = asyncio.wait_for(task, 180.0, loop=loop) - exitcode, stdout = yield from task + task = asyncio.wait_for(task, 420.0) + exitcode, output, status = yield from task else: if search == False: command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap_' + maptype + '.js "' + SACSID + '" "' + CSRF + '" "' + url + '" "' + filepath + '" "' + plugins + '"' task = _get_lines(command) - task = asyncio.wait_for(task, 180.0, loop=self.loop) - exitcode, stdout = loop.run_until_complete(task) + task = asyncio.wait_for(task, 420.0) + exitcode, output, status = yield from task else: command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap_' + maptype + '.js "' + SACSID + '" "' + CSRF + '" "' + url + '" "' + filepath + '" "' + search + '" "' + plugins + '"' task = _get_lines(command) - task = asyncio.wait_for(task, 180.0, loop=loop) - exitcode, stdout = yield from task + task = asyncio.wait_for(task, 420.0) + exitcode, output, status = yield from task # read the resulting file into a byte array + # yield from asyncio.sleep(10) file_resource = yield from _open_file(filepath) file_data = yield from loop.run_in_executor(None, file_resource.read) image_data = yield from loop.run_in_executor(None, io.BytesIO, file_data) - try: - image_id = yield from bot._client.upload_image(image_data, filename=filename) - yield from bot._client.sendchatmessage(event.conv.id_, None, image_id=image_id) - except Exception as e: - yield from bot.coro_send_message(event.conv_id, "<i>error uploading screenshot</i>") - logger.exception("upload failed".format(url)) + if status: + try: + image_id = yield from bot._client.upload_image(image_data, filename=filename) + yield from bot._client.sendchatmessage(event.conv.id_, None, image_id=image_id) + except Exception as e: + logger.exception("upload failed: {}".format(url)) + logger.exception("exception: {}".format(e)) + yield from bot.coro_send_message(event.conv_id, "<i>error uploading screenshot</i>") def setintel(bot, event, *args): @@ -168,14 +170,21 @@ def intel(bot, event, *args): url = bot.conversation_memory_get(event.conv_id, 'IntelURL') if bot.config.exists(["intel_screenbot", "SACSID"]): - SACSID = bot.config.get_by_path(["intel_screenbot", "SACSID"]) - else: - html = "<i><b>{}</b> No Intel SACSID Cookie has been added to config. Unable to authenticate".format(event.user.full_name) - yield from bot.coro_send_message(event.conv, html) - if bot.config.exists(["intel_screenbot", "CSRF"]): - CSRF = bot.config.get_by_path(["intel_screenbot", "CSRF"]) + if bot.config.exists(["intel_screenbot", "CSRF"]): + SACSID = bot.config.get_by_path(["intel_screenbot", "SACSID"]) + CSRF = bot.config.get_by_path(["intel_screenbot", "CSRF"]) + else: + html = "<i><b>{}</b> No Intel password has been added to config. Unable to authenticate".format(event.user.full_name) + yield from bot.coro_send_message(event.conv, html) + elif bot.config.exists(["intel_screenbot", "email"]): + if bot.config.exists(["intel_screenbot", "password"]): + SACSID = bot.config.get_by_path(["intel_screenbot", "email"]) + CSRF = bot.config.get_by_path(["intel_screenbot", "password"]) + else: + html = "<i><b>{}</b> No Intel password has been added to config. Unable to authenticate".format(event.user.full_name) + yield from bot.coro_send_message(event.conv, html) else: - html = "<i><b>{}</b> No Intel CSRF Cookie has been added to config. Unable to authenticate".format(event.user.full_name) + html = "<i><b>{}</b> No Intel SACSID Cookie or Email/password has been added to config. Unable to authenticate".format(event.user.full_name) yield from bot.coro_send_message(event.conv, html) if url is None: @@ -200,8 +209,8 @@ def intel(bot, event, *args): url = 'https://www.ingress.com/intel' yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting as requested, please wait...</i>") - filename = event.conv_id + "." + str(time.time()) +".png" - filepath = tempfile.NamedTemporaryFile(prefix=event.conv_id, suffix=".png", delete=False).name + filepath = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name + filename = filepath.split('/', filepath.count('/'))[-1] logger.debug("temporary screenshot file: {}".format(filepath)) try: loop = asyncio.get_event_loop() @@ -227,16 +236,23 @@ def iitc(bot, event, *args): url = bot.conversation_memory_get(event.conv_id, 'IntelURL') if bot.config.exists(["intel_screenbot", "SACSID"]): - SACSID = bot.config.get_by_path(["intel_screenbot", "SACSID"]) - else: - html = "<i><b>{}</b> No Intel SACSID Cookie has been added to config. Unable to authenticate".format(event.user.full_name) - yield from bot.coro_send_message(event.conv, html) - if bot.config.exists(["intel_screenbot", "CSRF"]): - CSRF = bot.config.get_by_path(["intel_screenbot", "CSRF"]) + if bot.config.exists(["intel_screenbot", "CSRF"]): + SACSID = bot.config.get_by_path(["intel_screenbot", "SACSID"]) + CSRF = bot.config.get_by_path(["intel_screenbot", "CSRF"]) + else: + html = "<i><b>{}</b> No Intel password has been added to config. Unable to authenticate".format(event.user.full_name) + yield from bot.coro_send_message(event.conv, html) + elif bot.config.exists(["intel_screenbot", "email"]): + if bot.config.exists(["intel_screenbot", "password"]): + SACSID = bot.config.get_by_path(["intel_screenbot", "email"]) + CSRF = bot.config.get_by_path(["intel_screenbot", "password"]) + else: + html = "<i><b>{}</b> No Intel password has been added to config. Unable to authenticate".format(event.user.full_name) + yield from bot.coro_send_message(event.conv, html) else: - html = "<i><b>{}</b> No Intel CSRF Cookie has been added to config. Unable to authenticate".format(event.user.full_name) + html = "<i><b>{}</b> No Intel SACSID Cookie or Email/password has been added to config. Unable to authenticate".format(event.user.full_name) yield from bot.coro_send_message(event.conv, html) - + if url is None: html = "<i><b>{}</b> No Intel URL has been set for screenshots.".format(event.user.full_name) yield from bot.coro_send_message(event.conv, html) @@ -259,8 +275,8 @@ def iitc(bot, event, *args): url = 'https://www.ingress.com/intel' yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting as requested, please wait...</i>") - filename = event.conv_id + "." + str(time.time()) +".png" - filepath = tempfile.NamedTemporaryFile(prefix=event.conv_id, suffix=".png", delete=False).name + filepath = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name + filename = filepath.split('/', filepath.count('/'))[-1] plugins_filepath = tempfile.NamedTemporaryFile(prefix=event.conv_id, suffix=".json", delete=False).name logger.debug("temporary screenshot file: {}".format(filepath)) if bot.conversation_memory_get(event.conv_id, 'iitc_plugins'): @@ -273,10 +289,10 @@ def iitc(bot, event, *args): plugins.append(plugin_objects["url"]) else: plugins = '' - + with open(plugins_filepath, 'w') as out: out.write(json.dumps(plugins)) - + try: loop = asyncio.get_event_loop() image_data = yield from _screencap("iitc", url, filepath, filename, SACSID, CSRF, plugins_filepath, search, bot, event) diff --git a/screencap_iitc.js b/screencap_iitc.js @@ -2,6 +2,8 @@ var system = require('system'); var args = system.args; var page = require('webpage').create(); var fs = require('fs'); +var cookiespath = '.iced_cookies'; +var config = ''; if (args.length === 1) { console.log('Try to pass some args when invoking this script!'); } else { @@ -12,6 +14,7 @@ if (args.length === 1) { var filepath = args[4]; var plugins_file = args[5]; var search = 'nix'; + var loginTimeout = '5000'; }else{ if (args.length === 7){ var SACSID = args[1]; @@ -20,10 +23,200 @@ if (args.length === 1) { var filepath = args[4]; var search = args[5]; var plugins_file = args[6]; + var loginTimeout = '5000'; } } } +function validateEmail(email) { + var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + return re.test(email); +} + +function quit(err) { + phantom.exit(0); +} +if (validateEmail(SACSID)) { + loadCookies(function() { + if (config.SACSID == undefined || config.SACSID == '') { + firePlainLogin(SACSID, CSRF); + } else { + addCookies(config.SACSID, config.CSRF); + console.log('Using cookies to log in'); + afterCookieLogin(); + } + }); +}else { + addCookies(SACSID, CSRF); + afterCookieLogin(IntelURL, search); +} + +function loadCookies(callback) { + if(fs.exists(cookiespath)) { + var stream = fs.open(cookiespath, 'r'); + + while(!stream.atEnd()) { + var line = stream.readLine().split('='); + if(line[0] === 'SACSID') { + config.SACSID = line[1]; + } else if(line[0] === 'csrftoken') { + config.CSRF = line[1]; + } else { + config.SACSID = ''; + config.CSRF = ''; + } + } + stream.close(); + } + callback(); +} + +function isSignedIn() { + return page.evaluate(function() { + return document.getElementsByTagName('a')[0].innerText.trim() !== 'Sign in'; + }); +} + +function storeCookies() { + var cookies = page.cookies; + fs.write(cookiespath, '', 'w'); + for(var i in cookies) { + fs.write(cookiespath, cookies[i].name + '=' + cookies[i].value +'\n', 'a'); + } +} + +function firePlainLogin(SACSID, CSRF) { + page.open('https://www.ingress.com/intel', function (status) { + page.evaluate(function () { + localStorage.clear() + }); + if (status !== 'success') {quit('unable to connect to remote server')} + var link = 'https://www.google.com/accounts/ServiceLogin?service=ah&passive=true&continue=https://appengine.google.com/_ah/conflogin%3Fcontinue%3Dhttps://www.ingress.com/intel&ltmpl=' + page.open(link, function () { + login(SACSID, CSRF); + }); + }); +} + +function login(l, p) { + if (document.querySelector('#timeoutError')){ + login(l, p) + firePlainLogin(l, p) + } + waitFor({ + timeout: loginTimeout*2, + check: function () { + return page.evaluate(function() { + if (document.querySelector('#gaia_loginform')) { + return true; + }else{ + return false; + } + }); + }, + success: function () { + page.evaluate(function (l) { + document.getElementById('Email').value = l; + }, l); + page.evaluate(function () { + document.querySelector("#next").click(); + }); + window.setTimeout(function () { + page.evaluate(function (p) { + document.getElementById('Passwd').value = p; + }, p); + if(document.querySelector("#next")){ + page.evaluate(function () { + document.querySelector("#next").click(); + }); + }else{ + page.evaluate(function () { + document.querySelector("#signIn").click(); + }); + } + window.setTimeout(function () { + if (page.url.substring(0,40) === 'https://accounts.google.com/ServiceLogin') { + quit('login failed: wrong email and/or password'); + } + + if (page.url.substring(0,40) === 'https://appengine.google.com/_ah/loginfo') { + page.evaluate(function () { + document.getElementById('persist_checkbox').checked = true; + document.getElementsByTagName('form').submit(); + }); + } + + if (page.url.substring(0,44) === 'https://accounts.google.com/signin/challenge') { + twostep = system.stdin.readLine(); + } + window.setTimeout(afterPlainLogin(IntelURL, search), loginTimeout); + }, loginTimeout) + }, loginTimeout / 10); + }, + error: function () { + quit(); + } + }); +} + +function afterPlainLogin(IntelURL, search) { + page.viewportSize = { width: '1280', height: '720' }; + page.open(IntelURL, function(status) { + if (status !== 'success') {quit('unable to connect to remote server')} + if (!isSignedIn()) { + console.log("not logged in") + quit(); + } + setTimeout(function() { + setupIITC() + setTimeout(function() { + setTimeout(function() {if (search != "nix") {searchfunc(search);}}, 1000); + waitFor({ + timeout: 240000, + check: function () { + return page.evaluate(function() { + if (document.querySelector('.map').textContent.indexOf('done') != -1) { + return true; + }else{ + console.log('generateFakeOutput') + return false; + } + }); + }, + success: function () { + var startTime = new Date().getTime(); + var interval = setInterval(function(){ + if(new Date().getTime() - startTime > 5000){ + hideDebris(); + prepare('1280', '720'); + main(); + clearInterval(interval); + return; + } + console.log('generateFakeOutput') + }, 1000); + }, + error: function () { + var startTime = new Date().getTime(); + var interval = setInterval(function(){ + if(new Date().getTime() - startTime > 5000){ + hideDebris(); + prepare('1280', '720'); + main(); + clearInterval(interval); + return; + } + console.log('generateFakeOutput') + }, 1000); + } + }); + }, "1000"); + }, "1000"); + }); +} + + + function addCookies(sacsid, csrf) { phantom.addCookie({ name: 'SACSID', @@ -46,11 +239,9 @@ function waitFor ($config) { $config._start = $config._start || new Date(); if ($config.timeout && new Date - $config._start > $config.timeout) { if ($config.error) $config.error(); - if ($config.debug) console.log('timedout ' + (new Date - $config._start) + 'ms'); return; } if ($config.check()) { - if ($config.debug) console.log('success ' + (new Date - $config._start) + 'ms'); return $config.success(); } setTimeout(waitFor, $config.interval || 0, $config); @@ -69,95 +260,141 @@ function loadLocalIitcPlugin(src) { page.injectJs(src) } -addCookies(SACSID, CSRF); -afterCookieLogin(IntelURL, search); - function afterCookieLogin(IntelURL, search) { - page.viewportSize = { width: '1920', height: '1080' }; + page.viewportSize = { width: '1280', height: '720' }; page.open(IntelURL, function(status) { if (status !== 'success') {quit('unable to connect to remote server')} - page.injectJs('https://code.jquery.com/jquery-3.1.1.min.js'); + if(!isSignedIn()) { + if(fs.exists(cookiespath)) { + fs.remove(cookiespath); + } + if(validateEmail(SACSID)) { + page.deleteCookie('SACSID'); + page.deleteCookie('csrftoken'); + firePlainLogin(SACSID, CSRF); + return; + } else { + quit('Cookies are obsolete. Update your config file.'); + } + } setTimeout(function() { - page.evaluate(function() { - localStorage['ingress.intelmap.layergroupdisplayed'] = JSON.stringify({ - "Unclaimed Portals":Boolean(1 === 1), - "Level 1 Portals":Boolean(1 === 1), - "Level 2 Portals":Boolean((1 <= 2) && (8 >= 2)), - "Level 3 Portals":Boolean((1 <= 3) && (8 >= 3)), - "Level 4 Portals":Boolean((1 <= 4) && (8 >= 4)), - "Level 5 Portals":Boolean((1 <= 5) && (8 >= 5)), - "Level 6 Portals":Boolean((1 <= 6) && (8 >= 6)), - "Level 7 Portals":Boolean((1 <= 7) && (8 >= 7)), - "Level 8 Portals":Boolean(8 === 8), - "DEBUG Data Tiles":false, - "Artifacts":true, - "Ornaments":true - }); - var script = document.createElement('script'); - script.type='text/javascript'; - script.src='https://secure.jonatkins.com/iitc/release/total-conversion-build.user.js'; - document.head.insertBefore(script, document.head.lastChild); - }); - loadIitcPlugin('http://iitc.jonatkins.com/release/plugins/canvas-render.user.js'); - var plugins = JSON.parse(fs.read(plugins_file)); - for(var i in plugins){ - var plugin = plugins[i]; - if(plugin.match('^[a-zA-Z]+://')){ - loadIitcPlugin(plugin); - }else{ - loadLocalIitcPlugin(plugin); - } - } + setupIITC() setTimeout(function() { - if (search != "nix") { - page.evaluate(function(search) { - if (document.querySelector('#search')){ - window.setTimeout(function() { - document.getElementById("search").value=search; - var e = jQuery.Event("keypress"); - e.which = 13; - e.keyCode = 13; - $("#search").trigger(e); - }, 2000); - var checkExist = setInterval(function() { - if ($('.searchquery').length > 0) { - window.setTimeout(function() {$('.searchquery > :nth-child(2)').children()[0].click();}, 1000); - clearInterval(checkExist); - } - }, 100); - } - }, search); - } + if (search != "nix") {searchfunc(search);} waitFor({ - timeout: 120000, + timeout: 240000, check: function () { return page.evaluate(function() { if (document.querySelector('.map').textContent.indexOf('done') != -1) { return true; }else{ + console.log('generateFakeOutput') return false; } }); }, success: function () { - hideDebris(); - prepare('1920', '1080'); - main(); + var startTime = new Date().getTime(); + var interval = setInterval(function(){ + if(new Date().getTime() - startTime > 5000){ + hideDebris(); + prepare('1280', '720'); + main(); + clearInterval(interval); + return; + } + console.log('generateFakeOutput') + }, 1000); }, error: function () { - hideDebris(); - prepare('1920', '1080'); - main(); + var startTime = new Date().getTime(); + var interval = setInterval(function(){ + if(new Date().getTime() - startTime > 5000){ + hideDebris(); + prepare('1280', '720'); + main(); + clearInterval(interval); + return; + } + console.log('generateFakeOutput') + }, 1000); } }); - }, "5000"); - }, "5000"); + }, "1000"); + }, "1000"); }); } +function searchfunc(search){ + page.evaluate(function(search) { + if (document.querySelector('#search')){ + window.addHook('search', function(query) { + var checkExist = setInterval(function() { + if (query.results.length > 0) { + console.warn(query.results) + map.fitBounds(query.results[0].bounds, {maxZoom: 17}) + clearInterval(checkExist); + } + }, 100); + }); + setTimeout(function() { + window.search.doSearch(search, true) + }, 2000); + } + }, search); +} + +function setupIITC(){ + loadIitcPlugin('https://static.iitc.me/build/release/plugins/canvas-render.user.js'); + page.evaluate(function() { + localStorage['ingress.intelmap.layergroupdisplayed'] = JSON.stringify({ + "Unclaimed Portals": true, + "Level 1 Portals": true, + "Level 2 Portals": true, + "Level 3 Portals": true, + "Level 4 Portals": true, + "Level 5 Portals": true, + "Level 6 Portals": true, + "Level 7 Portals": true, + "Level 8 Portals": true, + "Fields": true, + "Links": true, + "Resistance": true, + "Enlightened": true, + "DEBUG Data Tiles":false, + "Artifacts":true, + "Ornaments":true + }); + var script = document.createElement('script'); + script.type='text/javascript'; + script.src='https://static.iitc.me/build/test/total-conversion-build.user.js'; + document.head.insertBefore(script, document.head.lastChild); + localStorage['iitc-base-map'] = 'Google Roads'; + }); + var plugins = JSON.parse(fs.read(plugins_file)); + for(var i in plugins){ + var plugin = plugins[i]; + if(plugin.match('^[a-zA-Z]+://')){ + loadIitcPlugin(plugin); + }else{ + loadLocalIitcPlugin(plugin); + } + } +} + function s(file) { + console.log('SCREENSHOT') page.render(file); - phantom.exit(0); + var startTime = new Date().getTime(); + var startTime = new Date().getTime(); + var interval = setInterval(function(){ + if(new Date().getTime() - startTime > 5000){ + clearInterval(interval); + phantom.exit(0); + return; + } + console.log('doSomeOutput') + }, 1000); } function hideDebris() { @@ -170,14 +407,14 @@ function hideDebris() { if (document.querySelector('#sidebartoggle')) {document.querySelector('#sidebartoggle').style.display = 'none';} if (document.querySelector('#scrollwrapper')) {document.querySelector('#scrollwrapper').style.display = 'none';} if (document.querySelector('.leaflet-control-container')) {document.querySelector('.leaflet-control-container').style.display = 'none';} + if (document.querySelector('#portal_highlight_select')) {document.querySelector('#portal_highlight_select').style.display = 'none';} }); - }, 2000); + }, 200); } function prepare(widthz, heightz) { - window.setTimeout(function() { - page.evaluate(function(w, h) { - $("span:contains(' Google Roads')").prev().click(); + window.setTimeout(function() { + page.evaluate(function(w, h) { var water = document.createElement('p'); water.id='viewport-ice'; water.style.position = 'absolute'; @@ -188,10 +425,10 @@ function prepare(widthz, heightz) { water.style.width = w + 'px'; water.style.height = h + 'px'; document.querySelectorAll('body')[0].appendChild(water); - }, widthz, heightz); - var selector = "#viewport-ice"; - setElementBounds(selector); - }, 4000); + }, widthz, heightz); + var selector = "#viewport-ice"; + setElementBounds(selector); + }, 500); } @@ -241,10 +478,10 @@ function getDateTime(format) { } function addTimestamp(time) { - page.evaluate(function(dateTime) { + page.evaluate(function(dateTime, search) { var water = document.createElement('p'); water.id='watermark-ice'; - water.innerHTML = dateTime; + water.innerHTML = dateTime + ' - ' + search; water.style.position = 'absolute'; water.style.color = '#3A539B'; water.style.top = '0'; @@ -255,9 +492,9 @@ function addTimestamp(time) { water.style.fontSize = '40px'; water.style.opacity = '0.8'; water.style.fontFamily = 'monospace'; - water.style.textShadow = 'rgb(3, 3, 3) 7px 5px 9px'; + water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)'; document.querySelectorAll('body')[0].appendChild(water); - }, time); + }, time, search); } /** @@ -274,5 +511,5 @@ function main() { addTimestamp(getDateTime(0)); file = filepath; s(file); - }, 3000); + }, 400); } diff --git a/screencap_intel.js b/screencap_intel.js @@ -2,6 +2,8 @@ var system = require('system') var args = system.args; var page = require('webpage').create(); var fs = require('fs'); +var cookiespath = '.iced_cookies'; +var config = ''; if (args.length === 1) { console.log('Try to pass some args when invoking this script!'); } else { @@ -11,6 +13,7 @@ if (args.length === 1) { var IntelURL = args[3]; var filepath = args[4]; var search = 'nix'; + var loginTimeout = '10000'; }else{ if (args.length === 6){ var SACSID = args[1]; @@ -18,12 +21,203 @@ if (args.length === 1) { var IntelURL = args[3]; var filepath = args[4]; var search = args[5]; + var loginTimeout = '10000'; } } } -addCookies(SACSID,CSRF); -afterCookieLogin(IntelURL, search); +function validateEmail(email) { + var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + return re.test(email); +} + +function quit(err) { + phantom.exit(1); +} + +if (validateEmail(SACSID)) { + loadCookies(function() { + if (config.SACSID == undefined || config.SACSID == '') { + firePlainLogin(SACSID, CSRF); + } else { + addCookies(config.SACSID, config.CSRF); + console.log('Using cookies to log in'); + afterCookieLogin(); + } + }); +}else { + addCookies(SACSID, CSRF); + afterCookieLogin(IntelURL, search); +} + +function firePlainLogin(SACSID, CSRF) { + page.open('https://www.ingress.com/intel', function (status) { + page.evaluate(function () { + localStorage.clear() + }); + if (status !== 'success') {quit('unable to connect to remote server')} + + var link = 'https://www.google.com/accounts/ServiceLogin?service=ah&passive=true&continue=https://appengine.google.com/_ah/conflogin%3Fcontinue%3Dhttps://www.ingress.com/intel&ltmpl=' + + page.open(link, function () { + login(SACSID, CSRF); + }); + }); +} + +function loadCookies(callback) { + if(fs.exists(cookiespath)) { + var stream = fs.open(cookiespath, 'r'); + + while(!stream.atEnd()) { + var line = stream.readLine().split('='); + if(line[0] === 'SACSID') { + config.SACSID = line[1]; + } else if(line[0] === 'csrftoken') { + config.CSRF = line[1]; + } else { + config.SACSID = ''; + config.CSRF = ''; + } + } + stream.close(); + } + callback(); +} + +function isSignedIn() { + return page.evaluate(function() { + return document.getElementsByTagName('a')[0].innerText.trim() !== 'Sign in'; + }); +} + +function storeCookies() { + var cookies = page.cookies; + fs.write(cookiespath, '', 'w'); + for(var i in cookies) { + fs.write(cookiespath, cookies[i].name + '=' + cookies[i].value +'\n', 'a'); + } +} + +function login(l, p) { + if (document.querySelector('#timeoutError')){ + login(l, p) + firePlainLogin(l, p) + } + waitFor({ + timeout: 240000, + check: function () { + return page.evaluate(function() { + if (document.querySelector('#gaia_loginform')) { + return true; + }else{ + return false; + } + }); + }, + success: function () { + page.evaluate(function (l) { + document.getElementById('Email').value = l; + }, l); + page.evaluate(function () { + document.querySelector("#next").click(); + }); + window.setTimeout(function () { + page.evaluate(function (p) { + document.getElementById('Passwd').value = p; + }, p); + if(document.querySelector("#next")){ + page.evaluate(function () { + document.querySelector("#next").click(); + }); + }else{ + page.evaluate(function () { + document.querySelector("#signIn").click(); + }); + } +// page.evaluate(function () { +// document.getElementById('gaia_loginform').submit(); +// }); + window.setTimeout(function () { + if (page.url.substring(0,40) === 'https://accounts.google.com/ServiceLogin') { + quit('login failed: wrong email and/or password'); + } + + if (page.url.substring(0,40) === 'https://appengine.google.com/_ah/loginfo') { + page.evaluate(function () { + document.getElementById('persist_checkbox').checked = true; + document.getElementsByTagName('form').submit(); + }); + } + + if (page.url.substring(0,44) === 'https://accounts.google.com/signin/challenge') { + twostep = system.stdin.readLine(); + } + + // if (twostep) { + // page.evaluate(function (code) { + // document.getElementById('totpPin').value = code; + // }, twostep); + // page.evaluate(function () { + // document.getElementById('submit').click(); + // document.getElementById('challenge').submit(); + // }); + // } + window.setTimeout(afterPlainLogin(IntelURL, search), loginTimeout); + }, loginTimeout) + }, loginTimeout / 10); + }, + error: function () { + quit(); + } + }); +} + +function afterPlainLogin(IntelURL, search) { + page.open(IntelURL, function(status) { + if (status !== 'success') {quit('unable to connect to remote server')} + + if (!isSignedIn()) { + console.log('Something went wrong. Please, sign in to Google via your browser and restart ICE. Don\'t worry, your Ingress account will not be affected.'); + quit(); + } + setTimeout(function() { + storeCookies(); + waitFor({ + timeout: 240000, + check: function () { + return page.evaluate(function() { + if (document.querySelector('#percent_text').textContent.indexOf('90') != -1) { + if (!document.getElementById("loading_msg").style.display){ + return true; + }else{ + return false; + } + }else{ + return false; + } + }); + }, + success: function () { + page.evaluate(function() { + document.querySelector("#filters_container").style.display= 'none'; + }); + hideDebris(); + prepare('1920', '1080', search); + main(); + }, + error: function () { + page.evaluate(function() { + document.querySelector("#filters_container").style.display= 'none'; + }); + hideDebris(); + prepare('1920', '1080', search); + main(); + } + }); + }, "5000"); + }); +} function addCookies(sacsid, csrf) { phantom.addCookie({ @@ -59,10 +253,22 @@ function waitFor ($config) { function afterCookieLogin(IntelURL, search) { page.open(IntelURL, function(status) { if (status !== 'success') {quit('unable to connect to remote server')} - + if(!isSignedIn()) { + if(fs.exists(cookiespath)) { + fs.remove(cookiespath); + } + if(validateEmail(SACSID)) { + page.deleteCookie('SACSID'); + page.deleteCookie('csrftoken'); + firePlainLogin(SACSID, CSRF); + return; + } else { + quit('Cookies are obsolete. Update your config file.'); + } + } setTimeout(function() { waitFor({ - timeout: 120000, + timeout: 240000, check: function () { return page.evaluate(function() { if (document.querySelector('#percent_text').textContent.indexOf('90') != -1) {