commit 89aa1e08f855c6e7be620a6c10f8b3960c6c3244
Author: Phorge Migration <migration@localhost>
Date: Tue, 21 Jul 2026 18:08:02 +0200
Archive issues/PRs export for MTRNord/intel_screenbot
Diffstat:
26 files changed, 4950 insertions(+), 0 deletions(-)
diff --git a/issues/3.json b/issues/3.json
@@ -0,0 +1,16 @@
+{
+ "number": 3,
+ "title": "Wait longer when loading Stock intel",
+ "state": "closed",
+ "author": "MTRNord",
+ "created_at": "2016-11-16T05:45:11Z",
+ "closed_at": "2016-11-16T09:30:17Z",
+ "labels": [
+ "enhancement"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "body": "Intel fails because timeout kicks in to soon",
+ "comments": []
+}
diff --git a/issues/3.md b/issues/3.md
@@ -0,0 +1,13 @@
+# #3 Wait longer when loading Stock intel
+
+- **State:** closed
+- **Author:** @MTRNord
+- **Created:** 2016-11-16T05:45:11Z
+- **Closed:** 2016-11-16T09:30:17Z
+- **Labels:** enhancement
+- **Assignees:** @MTRNord
+
+---
+
+Intel fails because timeout kicks in to soon
+
diff --git a/issues/6.json b/issues/6.json
@@ -0,0 +1,17 @@
+{
+ "number": 6,
+ "title": "Detect non intel links as wrong",
+ "state": "open",
+ "author": "MTRNord",
+ "created_at": "2017-02-12T11:41:10Z",
+ "closed_at": null,
+ "labels": [
+ "bug",
+ "enhancement"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "body": "Currently it starts a phantomjs process even If it is not a allowed link. ",
+ "comments": []
+}
diff --git a/issues/6.md b/issues/6.md
@@ -0,0 +1,12 @@
+# #6 Detect non intel links as wrong
+
+- **State:** open
+- **Author:** @MTRNord
+- **Created:** 2017-02-12T11:41:10Z
+- **Labels:** bug, enhancement
+- **Assignees:** @MTRNord
+
+---
+
+Currently it starts a phantomjs process even If it is not a allowed link.
+
diff --git a/issues/8.json b/issues/8.json
@@ -0,0 +1,21 @@
+{
+ "number": 8,
+ "title": "Switch phantomjs to ChromeHeadless",
+ "state": "open",
+ "author": "MTRNord",
+ "created_at": "2017-07-08T09:26:33Z",
+ "closed_at": null,
+ "labels": [
+ "enhancement",
+ "help wanted"
+ ],
+ "assignees": [],
+ "body": "",
+ "comments": [
+ {
+ "author": "MTRNord",
+ "created_at": "2017-09-10T09:47:17Z",
+ "body": "Also switching js to golang \\\\(^^)/"
+ }
+ ]
+}
diff --git a/issues/8.md b/issues/8.md
@@ -0,0 +1,18 @@
+# #8 Switch phantomjs to ChromeHeadless
+
+- **State:** open
+- **Author:** @MTRNord
+- **Created:** 2017-07-08T09:26:33Z
+- **Labels:** enhancement, help wanted
+
+---
+
+_No description._
+
+
+## Comments
+
+### @MTRNord — 2017-09-10T09:47:17Z
+
+Also switching js to golang \\(^^)/
+
diff --git a/issues/9.json b/issues/9.json
@@ -0,0 +1,15 @@
+{
+ "number": 9,
+ "title": "Move Credentials to external file to make it more secure",
+ "state": "open",
+ "author": "MTRNord",
+ "created_at": "2017-07-08T20:54:44Z",
+ "closed_at": null,
+ "labels": [
+ "bug",
+ "enhancement"
+ ],
+ "assignees": [],
+ "body": "",
+ "comments": []
+}
diff --git a/issues/9.md b/issues/9.md
@@ -0,0 +1,11 @@
+# #9 Move Credentials to external file to make it more secure
+
+- **State:** open
+- **Author:** @MTRNord
+- **Created:** 2017-07-08T20:54:44Z
+- **Labels:** bug, enhancement
+
+---
+
+_No description._
+
diff --git a/pulls/1.diff b/pulls/1.diff
@@ -0,0 +1,1129 @@
+diff --git a/README.md b/README.md
+index 0d3c137..5dcbdb8 100644
+--- a/README.md
++++ b/README.md
+@@ -11,18 +11,23 @@ Get and post a screenshot of the Intel Map.
+ ## Install
+ To install the plugin you need to:
+
+-1. Clone this repo into `<yourBotDir>/plugins/`
+-2. Optional remove `README.md` `LICENSE` and `.gitignore`
+-3. Follow Configuration.
++1. Go into `<yourBotDir>/plugins/`
++2. Clone this repo into `intel_screenbot`
++3. Optional remove `README.md` `LICENSE` and `.gitignore` from `<yourBotDir>/plugins/intel_screenbot`
++4. Run `pip3 install -r requirements.txt`
++5. Follow Configuration.
+
+ ## Configuration
+ For using the Intel Screenbot you need to add the following to the config.json:
+
+ ```
+ "intel_screenbot": {
+- "SACSID": "YOUR SACSID",
+- "CSRF": "YOUR CSRF"
+- }
++ "SACSID": "YOUR SACSID",
++ "CSRF": "YOUR CSRF",
++ "plugin_dirs": [
++ "http://iitc.jonatkins.com/release/plugins"
++ ]
++ }
+ ```
+
+ According to the official INSTALL Documention of the hangoutbot you will find the config.json in `/<username>/.local/share/hangupsbot/`
+@@ -30,6 +35,25 @@ According to the official INSTALL Documention of the hangoutbot you will find th
+
+ Also you need to add `intel_screenbot` to the plugins.
+
++## How to add gitlab to plugin_dirs
++
++1. Open in browser: `https://gitlab.com/api/v3/projects/search/:REPO_NAME`
++2. copy the number in `id`
++3. add `http://gitlab.com/api/v3/projects/:ID/repository/tree` to `plugin_dirs`
++4. add `"gitlab_token":"YOUR_GITLAB_API_TOKEN"` to `intel_screenbot`
++
++*Note: repos are currently locked to master branch*
++
++## How to add github to plugins_dir
++
++1. add `https://api.github.com/repos/:REPO_USER/:REPO_NAME/git/trees/master?recursive=1`
++
++## How to add local files to plugins_dir
++
++1. just add the absolute path to `plugins_dir` (relative paths are not tested)
++
++*Note: repos are currently locked to master branch*
++
+ ## How to get SACSID and CSRF
+ You should look at the Documentation of [ingress-ice](https://github.com/nibogd/ingress-ice/wiki/Cookies-Authentication)
+
+@@ -41,13 +65,29 @@ You should look at the Documentation of [ingress-ice](https://github.com/nibogd/
+ `/bot clearintel`
+ * Clears the default screenshot URL of a particular hangout.
+
++`/bot show_iitcplugins`
++* Shows every availible IITC-plugin.
++
++`/bot set_iitcplugins <plugin names devided by whitespace>`
++* Sets the plugins to use with IITC per hangout.
++
++`/bot clear_iitcplugins`
++* Clear the plugins to use with IITC per hangout.
++
++
+ ## User Command
+
+-`/bot intel [<url>]`
++`/bot intel [<url> or <searchTerm>]`
+ * 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
++`/bot iitc [<url> or <searchTerm>]`
++* 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
++
++*May be outdated*
+
+ ### Debian-based distros (e.g. Ubuntu 14.04)
+
+diff --git a/__init__.py b/__init__.py
+new file mode 100644
+index 0000000..2648a61
+--- /dev/null
++++ b/__init__.py
+@@ -0,0 +1,315 @@
++from bs4 import BeautifulSoup
++import requests
++import json
++import asyncio, io, logging, os, re, time, tempfile
++import subprocess
++import plugins
++import re
++from asyncio import subprocess
++from shutil import move
++from os import remove, close
++
++logger = logging.getLogger(__name__)
++
++
++def _initialise(bot):
++ plugins.register_user_command(["intel", "iitc"])
++ plugins.register_admin_command(["setintel", "clearintel", "show_iitcplugins", "set_iitcplugins", "clear_iitcplugins"])
++ _get_iitc_plugins(bot)
++
++
++@asyncio.coroutine
++def _open_file(name):
++ logger.debug("opening screenshot file: {}".format(name))
++ return open(name, 'rb')
++
++def _parse_onlineRepos(url, ext=''):
++ logger.debug("parsing github or gitlab or http(s)")
++ page = requests.get(url).text
++ if 'gitlab.com' in url:
++ files = []
++ for json_page in json.loads(page):
++ for attribute, value in json_page.items():
++ if attribute == "name":
++ if value.endswith(ext):
++ files.append(url.replace("/tree/", "/blobs/master") + "&filepath=" + value)
++ return files
++ elif 'github.com' in url:
++ files = []
++ for attribute, value in json.loads(page).items():
++ if attribute == "tree":
++ for tree in value:
++ for attribute, value in tree.items():
++ if attribute == "path":
++ if value.endswith(ext):
++ 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:
++ soup = BeautifulSoup(page, 'html.parser')
++ return [url + '/' + node.get('href') for node in soup.find_all('a') if node.get('href').endswith(ext)]
++
++def _get_iitc_plugins(bot):
++ logger.debug("getting availible plugins")
++ if bot.config.exists(["intel_screenbot", "gitlab_token"]):
++ token = bot.config.get_by_path(["intel_screenbot", "gitlab_token"])
++ url_config = bot.config.get_by_path(["intel_screenbot", "plugin_dirs"])
++ ext = '.user.js'
++ data=[]
++ for url in url_config:
++ if ext in url:
++ item = {"name": url.split('/', url.count('/'))[-1].replace(ext, ''), "url": url}
++ data.append(item)
++ else:
++ if "gitlab.com" in url:
++ url = url + '?private_token=' + token
++ for file in _parse_onlineRepos(url, ext):
++ if "gitlab.com" in url:
++ item = {"name": file.split('=', file.count('='))[-1].replace(ext, ''), "url": file}
++ elif 'github.com' in url:
++ item = {"name": file.split('/', file.count('/'))[-1].replace(ext, ''), "url": file}
++ else:
++ item = {"name": file.split('/', file.count('/'))[-1].replace(ext, ''), "url": file}
++ data.append(item)
++
++ iitc_plugins = data
++ if bot.memory.exists(["iitc_plugins"]):
++ bot.memory.pop_by_path(["iitc_plugins"])
++ bot.memory.set_by_path(["iitc_plugins"], iitc_plugins)
++ 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
++
++@asyncio.coroutine
++def _screencap(maptype, url, filepath, filename, SACSID, CSRF, plugins, search, bot, event):
++ loop = asyncio.get_event_loop()
++ logger.info("screencapping {} and saving as {}".format(url, filepath))
++ if plugins is '':
++ 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)
++ 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
++ 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)
++ 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
++
++ # read the resulting file into a byte array
++ 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))
++
++
++def setintel(bot, event, *args):
++ """set url for current converation for the intel or iitc command.
++ use /bot clearintel to clear the previous url before setting a new one.
++ """
++ url = bot.conversation_memory_get(event.conv_id, 'IntelURL')
++ if url is None:
++ bot.conversation_memory_set(event.conv_id, 'IntelURL', ''.join(args))
++ html = "<i><b>{}</b> updated screenshot URL".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++
++ else:
++ html = "<i><b>{}</b> URL already exists for this conversation!<br /><br />".format(event.user.full_name)
++ html += "<i>Clear it first with /bot clearintel before setting a new one."
++ yield from bot.coro_send_message(event.conv, html)
++
++
++def clearintel(bot, event, *args):
++ """clear url for current converation for the intel or iitc command.
++ """
++ url = bot.conversation_memory_get(event.conv_id, 'IntelURL')
++ if url is None:
++ html = "<i><b>{}</b> nothing to clear for this conversation".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++
++ else:
++ bot.conversation_memory_set(event.conv_id, 'IntelURL', None)
++ html = "<i><b>{}</b> URL cleared for this conversation!<br />".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++
++
++def intel(bot, event, *args):
++ """get a screenshot of a search term or intel URL or the default intel URL of the hangout.
++ """
++
++ if args:
++ if len(args) > 1:
++ url = ' '.join(str(i) for i in args)
++ else:
++ url = args[0]
++ if '"' in url:
++ url = url.replace('"', '')
++ else:
++ 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"])
++ else:
++ html = "<i><b>{}</b> No Intel CSRF Cookie 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 or search term has been set for screenshots.".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++
++ else:
++ if re.match(r'^[a-zA-Z]+://', url):
++ search = False
++ ZoomSearch = re.finditer(r"(?:&z=).*", url)
++ for matchNum, zoomlevel_raw in enumerate(ZoomSearch):
++ matchNum = matchNum + 1
++ zoomlevel_clean = zoomlevel_raw.group()
++ zoomlevel = zoomlevel_clean[3:][:2]
++ if zoomlevel.isdigit():
++ yield from bot.coro_send_message(event.conv_id, "<i>intel map at zoom level "+ zoomlevel + " requested, please wait...</i>")
++ else:
++ yield from bot.coro_send_message(event.conv_id, "<i>intel map at last zoom level requested, please wait...</i>")
++ else:
++ search = url
++ logger.info(search);
++ 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
++ logger.debug("temporary screenshot file: {}".format(filepath))
++ try:
++ loop = asyncio.get_event_loop()
++ image_data = yield from _screencap("intel", url, filepath, filename, SACSID, CSRF, "", search, bot, event)
++ except Exception as e:
++ yield from bot.coro_send_message(event.conv_id, "<i>error getting screenshot</i>")
++ logger.exception("screencap failed".format(url))
++ return
++
++
++def iitc(bot, event, *args):
++ """get a screenshot of a search term or intel URL or the default intel URL of the hangout.
++ """
++
++ if args:
++ if len(args) > 1:
++ url = ' '.join(str(i) for i in args)
++ else:
++ url = args[0]
++ if '"' in url:
++ url = url.replace('"', '')
++ else:
++ 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"])
++ else:
++ html = "<i><b>{}</b> No Intel CSRF Cookie 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)
++
++ else:
++ if re.match(r'^[a-zA-Z]+://', url):
++ search = False
++ ZoomSearch = re.finditer(r"(?:&z=).*", url)
++ for matchNum, zoomlevel_raw in enumerate(ZoomSearch):
++ matchNum = matchNum + 1
++ zoomlevel_clean = zoomlevel_raw.group()
++ zoomlevel = zoomlevel_clean[3:][:2]
++ if zoomlevel.isdigit():
++ yield from bot.coro_send_message(event.conv_id, "<i>intel map at zoom level "+ zoomlevel + " requested, please wait...</i>")
++ else:
++ yield from bot.coro_send_message(event.conv_id, "<i>intel map at last zoom level requested, please wait...</i>")
++ else:
++ search = url
++ logger.info(search);
++ 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
++ 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'):
++ plugins = []
++ plugin_names = bot.conversation_memory_get(event.conv_id, 'iitc_plugins').split(", ")
++ if bot.memory.exists(["iitc_plugins"]):
++ for plugin_objects in bot.memory.get_by_path(["iitc_plugins"]):
++ for plugin_name in plugin_names:
++ if plugin_objects["name"] == plugin_name:
++ 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)
++ except Exception as e:
++ yield from bot.coro_send_message(event.conv_id, "<i>error getting screenshot</i>")
++ logger.exception("screencap failed".format(url))
++ return
++
++def show_iitcplugins(bot, event, *args):
++ if bot.memory.exists(["iitc_plugins"]):
++ plugin_names = []
++ for plugin_objects in bot.memory.get_by_path(["iitc_plugins"]):
++ for attribute, value in plugin_objects.items():
++ if attribute == "name":
++ plugin_names.append(value)
++ yield from bot.coro_send_to_user_and_conversation(event.user.id_.chat_id, event.conv_id, "<i><b>IITC Plugins:</b><br> {}</i>".format(', <br>'.join(str(i) for i in plugin_names)), _("<i><b>{}</b>, I've sent you the plugins ;)</i>").format(event.user.full_name))
++
++def set_iitcplugins(bot, event, *args):
++ if not bot.conversation_memory_get(event.conv_id, 'iitc_plugins') is None:
++ html = "<i><b>{}</b> plugins already set for this conversation!<br /><br />".format(event.user.full_name)
++ html += "<i>Clear them first with /bot clear_iitcplugins before setting new ones."
++ yield from bot.coro_send_message(event.conv, html)
++ else:
++ bot.conversation_memory_set(event.conv_id, 'iitc_plugins', ', '.join(args))
++ html = "<i><b>{}</b> updated plugins".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++
++def clear_iitcplugins(bot, event, *args):
++ if bot.conversation_memory_get(event.conv_id, 'iitc_plugins') is None:
++ html = "<i><b>{}</b> nothing to clear for this conversation".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++
++ else:
++ bot.conversation_memory_set(event.conv_id, 'iitc_plugins', None)
++ html = "<i><b>{}</b> plugins cleared for this conversation!<br />".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
+diff --git a/intel_screenbot/__init__.py b/intel_screenbot/__init__.py
+deleted file mode 100644
+index 880436e..0000000
+--- a/intel_screenbot/__init__.py
++++ /dev/null
+@@ -1,136 +0,0 @@
+-import asyncio, io, logging, os, re, time, tempfile
+-import subprocess
+-import plugins
+-import re
+-from asyncio import subprocess
+-
+-logger = logging.getLogger(__name__)
+-
+-
+-def _initialise(bot):
+- plugins.register_user_command(["intel"])
+- plugins.register_admin_command(["setintel", "clearintel"])
+-
+-@asyncio.coroutine
+-def _open_file(name):
+- logger.debug("opening screenshot file: {}".format(name))
+- return open(name, 'rb')
+-
+-@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
+-
+-@asyncio.coroutine
+-def _screencap(url, filepath, filename, SACSID, CSRF, search, bot, event):
+- loop = asyncio.get_event_loop()
+- logger.info("screencapping {} and saving as {}".format(url, filepath))
+- if search == False:
+- command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap.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)
+- else:
+- command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap.js "' + SACSID + '" "' + CSRF + '" "' + url + '" "' + filepath + '" "' + search + '"'
+- task = _get_lines(command)
+- task = asyncio.wait_for(task, 180.0, loop=loop)
+- exitcode, stdout = yield from task
+-
+- # read the resulting file into a byte array
+- 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))
+-
+-
+-def setintel(bot, event, *args):
+- """set url for current converation for the screenshot command.
+- use /bot clearintel to clear the previous url before setting a new one.
+- """
+- url = bot.conversation_memory_get(event.conv_id, 'IntelURL')
+- if url is None:
+- bot.conversation_memory_set(event.conv_id, 'IntelURL', ''.join(args))
+- html = "<i><b>{}</b> updated screenshot URL".format(event.user.full_name)
+- yield from bot.coro_send_message(event.conv, html)
+-
+- else:
+- html = "<i><b>{}</b> URL already exists for this conversation!<br /><br />".format(event.user.full_name)
+- html += "<i>Clear it first with /bot clearintel before setting a new one."
+- yield from bot.coro_send_message(event.conv, html)
+-
+-
+-def clearintel(bot, event, *args):
+- """clear url for current converation for the screenshot command.
+- """
+- url = bot.conversation_memory_get(event.conv_id, 'IntelURL')
+- if url is None:
+- html = "<i><b>{}</b> nothing to clear for this conversation".format(event.user.full_name)
+- yield from bot.coro_send_message(event.conv, html)
+-
+- else:
+- bot.conversation_memory_set(event.conv_id, 'IntelURL', None)
+- html = "<i><b>{}</b> URL cleared for this conversation!<br />".format(event.user.full_name)
+- yield from bot.coro_send_message(event.conv, html)
+-
+-
+-def intel(bot, event, *args):
+- """get a screenshot of a user provided URL or the default URL of the hangout.
+- """
+-
+- if args:
+- if len(args) > 1:
+- url = ' '.join(str(i) for i in args)
+- else:
+- url = args[0]
+- else:
+- 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"])
+- else:
+- html = "<i><b>{}</b> No Intel CSRF Cookie 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)
+-
+- else:
+- if re.match(r'^[a-zA-Z]+://', url):
+- search = False
+- ZoomSearch = re.finditer(r"(?:&z=).*", url)
+- for matchNum, zoomlevel_raw in enumerate(ZoomSearch):
+- matchNum = matchNum + 1
+- zoomlevel_clean = zoomlevel_raw.group()
+- zoomlevel = zoomlevel_clean[3:][:2]
+- if zoomlevel.isdigit():
+- yield from bot.coro_send_message(event.conv_id, "<i>intel map at zoom level "+ zoomlevel + " requested, please wait...</i>")
+- else:
+- yield from bot.coro_send_message(event.conv_id, "<i>intel map at last zoom level requested, please wait...</i>")
+- else:
+- search = url
+- logger.info(search);
+- 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
+- logger.debug("temporary screenshot file: {}".format(filepath))
+-
+- try:
+- loop = asyncio.get_event_loop()
+- image_data = yield from _screencap(url, filepath, filename, SACSID, CSRF, search, bot, event)
+- except Exception as e:
+- yield from bot.coro_send_message(event.conv_id, "<i>error getting screenshot</i>")
+- logger.exception("screencap failed".format(url))
+- return
+diff --git a/requirements.txt b/requirements.txt
+new file mode 100644
+index 0000000..9d981c3
+--- /dev/null
++++ b/requirements.txt
+@@ -0,0 +1,2 @@
++bs4
++requests
+diff --git a/screencap_iitc.js b/screencap_iitc.js
+new file mode 100644
+index 0000000..c9413db
+--- /dev/null
++++ b/screencap_iitc.js
+@@ -0,0 +1,278 @@
++var system = require('system');
++var args = system.args;
++var page = require('webpage').create();
++var fs = require('fs');
++if (args.length === 1) {
++ console.log('Try to pass some args when invoking this script!');
++} else {
++ if (args.length === 6){
++ var SACSID = args[1];
++ var CSRF = args[2];
++ var IntelURL = args[3];
++ var filepath = args[4];
++ var plugins_file = args[5];
++ var search = 'nix';
++ }else{
++ if (args.length === 7){
++ var SACSID = args[1];
++ var CSRF = args[2];
++ var IntelURL = args[3];
++ var filepath = args[4];
++ var search = args[5];
++ var plugins_file = args[6];
++ }
++ }
++}
++
++function addCookies(sacsid, csrf) {
++ phantom.addCookie({
++ name: 'SACSID',
++ value: sacsid,
++ domain: 'www.ingress.com',
++ path: '/',
++ httponly: true,
++ secure: true
++ });
++ phantom.addCookie({
++ name: 'csrftoken',
++ value: csrf,
++ domain: 'www.ingress.com',
++ path: '/'
++ });
++}
++
++
++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);
++}
++
++function loadIitcPlugin(src) {
++ page.evaluate(function(src) {
++ var script = document.createElement('script');
++ script.type='text/javascript';
++ script.src=src;
++ document.head.insertBefore(script, document.head.lastChild);
++ }, src);
++}
++
++function loadLocalIitcPlugin(src) {
++ page.injectJs(src)
++}
++
++addCookies(SACSID, CSRF);
++afterCookieLogin(IntelURL, search);
++
++function afterCookieLogin(IntelURL, search) {
++ page.viewportSize = { width: '1920', height: '1080' };
++ 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');
++ 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);
++ }
++ }
++ 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);
++ }
++ waitFor({
++ timeout: 120000,
++ check: function () {
++ return page.evaluate(function() {
++ if (document.querySelector('.map').textContent.indexOf('done') != -1) {
++ return true;
++ }else{
++ return false;
++ }
++ });
++ },
++ success: function () {
++ hideDebris();
++ prepare('1920', '1080');
++ main();
++ },
++ error: function () {
++ hideDebris();
++ prepare('1920', '1080');
++ main();
++ }
++ });
++ }, "5000");
++ }, "5000");
++ });
++}
++
++function s(file) {
++ page.render(file);
++ phantom.exit(0);
++}
++
++function hideDebris() {
++ window.setTimeout(function() {
++ page.evaluate(function() {
++ if (document.querySelector('#chat')) {document.querySelector('#chat').style.display = 'none';}
++ if (document.querySelector('#chatcontrols')) {document.querySelector('#chatcontrols').style.display = 'none';}
++ if (document.querySelector('#chatinput')) {document.querySelector('#chatinput').style.display = 'none';}
++ if (document.querySelector('#updatestatus')) {document.querySelector('#updatestatus').style.display = 'none';}
++ 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';}
++ });
++ }, 2000);
++}
++
++function prepare(widthz, heightz) {
++ window.setTimeout(function() {
++ page.evaluate(function(w, h) {
++ $("span:contains(' Google Roads')").prev().click();
++ var water = document.createElement('p');
++ water.id='viewport-ice';
++ water.style.position = 'absolute';
++ water.style.top = '0';
++ water.style.marginTop = '0';
++ water.style.paddingTop = '0';
++ water.style.left = '0';
++ 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);
++}
++
++
++function setElementBounds(selector) {
++ page.clipRect = page.evaluate(function(selector) {
++ var clipRect = document.querySelector(selector).getBoundingClientRect();
++ return {
++ top: clipRect.top,
++ left: clipRect.left,
++ width: clipRect.width,
++ height: clipRect.height
++ };
++ }, selector);
++}
++
++function getDateTime(format) {
++ var now = new Date();
++ var year = now.getFullYear();
++ var month = now.getMonth()+1;
++ var day = now.getDate();
++ var hour = now.getHours();
++ var minute = now.getMinutes();
++ var second = now.getSeconds();
++ var timeZone = '';
++ if(month.toString().length === 1) {
++ month = '0' + month;
++ }
++ if(day.toString().length === 1) {
++ day = '0' + day;
++ }
++ if(hour.toString().length === 1) {
++ hour = '0' + hour;
++ }
++ if(minute.toString().length === 1) {
++ minute = '0' + minute;
++ }
++ if(second.toString().length === 1) {
++ second = '0' + second;
++ }
++ var dateTime;
++ if (format === 1) {
++ dateTime = year + '-' + month + '-' + day + '--' + hour + '-' + minute + '-' + second;
++ } else {
++ dateTime = day + '.' + month + '.' + year + ' ' + hour + ':' + minute + ':' + second + timeZone;
++ }
++ return dateTime;
++}
++
++function addTimestamp(time) {
++ page.evaluate(function(dateTime) {
++ var water = document.createElement('p');
++ water.id='watermark-ice';
++ water.innerHTML = dateTime;
++ water.style.position = 'absolute';
++ water.style.color = '#3A539B';
++ water.style.top = '0';
++ water.style.zIndex = '4404';
++ water.style.marginTop = '0';
++ water.style.paddingTop = '0';
++ water.style.left = '0';
++ water.style.fontSize = '40px';
++ water.style.opacity = '0.8';
++ water.style.fontFamily = 'monospace';
++ water.style.textShadow = 'rgb(3, 3, 3) 7px 5px 9px';
++ document.querySelectorAll('body')[0].appendChild(water);
++ }, time);
++}
++
++/**
++ * Main function.
++ */
++function main() {
++ page.evaluate(function() {
++ if (document.getElementById('watermark-ice')) {
++ var oldStamp = document.getElementById('watermark-ice');
++ oldStamp.parentNode.removeChild(oldStamp);
++ }
++ });
++ window.setTimeout(function() {
++ addTimestamp(getDateTime(0));
++ file = filepath;
++ s(file);
++ }, 3000);
++}
+diff --git a/intel_screenbot/screencap.js b/screencap_intel.js
+similarity index 55%
+rename from intel_screenbot/screencap.js
+rename to screencap_intel.js
+index 9383f15..3ef8afc 100644
+--- a/intel_screenbot/screencap.js
++++ b/screencap_intel.js
+@@ -1,5 +1,5 @@
+ var system = require('system')
+-var args = require('system').args;
++var args = system.args;
+ var page = require('webpage').create();
+ var fs = require('fs');
+ if (args.length === 1) {
+@@ -18,31 +18,12 @@ if (args.length === 1) {
+ var IntelURL = args[3];
+ var filepath = args[4];
+ var search = args[5];
+- console.log(search)
+- system.stdout.writeLine(filepath);
+ }
+ }
+ }
+
+-addCookies(SACSID,CSRF)
+-afterCookieLogin(IntelURL, search)
+-
+-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);
+-}
++addCookies(SACSID,CSRF);
++afterCookieLogin(IntelURL, search);
+
+ function addCookies(sacsid, csrf) {
+ phantom.addCookie({
+@@ -61,26 +42,30 @@ function addCookies(sacsid, csrf) {
+ });
+ }
+
++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);
++}
+
+-/**
+- * Does all stuff needed after cookie authentication
+- * @since 3.1.0
+- */
+ function afterCookieLogin(IntelURL, search) {
+ page.open(IntelURL, function(status) {
+ if (status !== 'success') {quit('unable to connect to remote server')}
+
+- if(!isSignedIn()) {
+- if(fs.exists('.iced_cookies')) {
+- fs.remove('.iced_cookies');
+- }
+- }
+ setTimeout(function() {
+ waitFor({
+ timeout: 120000,
+ check: function () {
+ return page.evaluate(function() {
+- if (document.querySelector('#percent_text').textContent == "90") {
++ if (document.querySelector('#percent_text').textContent.indexOf('90') != -1) {
+ if (!document.getElementById("loading_msg").style.display){
+ return true;
+ }else{
+@@ -100,91 +85,58 @@ function afterCookieLogin(IntelURL, search) {
+ main();
+ },
+ error: function () {
+- system.stdout.writeLine('map did not finish loading in time...');
+ page.evaluate(function() {
+ document.querySelector("#filters_container").style.display= 'none';
+ });
+ hideDebris();
+ prepare('1920', '1080', search);
+ main();
+- } // optional
++ }
+ });
+ }, "5000");
+ });
+ }
+
+-/**
+- * Checks if user is signed in by looking for the "Sign in" button
+- * @returns {boolean}
+- * @since 3.2.0
+- */
+-function isSignedIn() {
+- return page.evaluate(function() {
+- return document.getElementsByTagName('a')[0].innerText.trim() !== 'Sign in';
+- });
+-}
+-
+-function storeCookies() {
+- var cookies = page.cookies;
+- fs.write('.iced_cookies', '', 'w');
+- for(var i in cookies) {
+- fs.write('.iced_cookies', cookies[i].name + '=' + cookies[i].value +'\n', 'a');
+- }
+-}
+-
+ function s(file) {
+ page.render(file);
+ phantom.exit(0);
+ }
+
+ function hideDebris() {
+- system.stdout.writeLine('hideDebris...');
+- page.evaluate(function() {
+- if (document.querySelector('#comm')) {document.querySelector('#comm').style.display = 'none';}
+- if (document.querySelector('#player_stats')) {document.querySelector('#player_stats').style.display = 'none';}
+- if (document.querySelector('#game_stats')) {document.querySelector('#game_stats').style.display = 'none';}
+- if (document.querySelector('#geotools')) {document.querySelector('#geotools').style.display = 'none';}
+- if (document.querySelector('#header')) {document.querySelector('#header').style.display = 'none';}
+- if (document.querySelector('#snapcontrol')) {document.querySelector('#snapcontrol').style.display = 'none';}
+- if (document.querySelectorAll('.img_snap')[0]) {document.querySelectorAll('.img_snap')[0].style.display = 'none';}
+- if (document.querySelector('#display_msg_text')) {document.querySelector('#display_msg_text').style.display = 'none';}
+- });
+- page.evaluate(function() {
+- var hide = document.querySelectorAll('.gmnoprint');
+- for (var index = 0; index < hide.length; ++index) {
+- hide[index].style.display = 'none';
+- }
+- });
++ page.evaluate(function() {
++ if (document.querySelector('#comm')) {document.querySelector('#comm').style.display = 'none';}
++ if (document.querySelector('#player_stats')) {document.querySelector('#player_stats').style.display = 'none';}
++ if (document.querySelector('#game_stats')) {document.querySelector('#game_stats').style.display = 'none';}
++ if (document.querySelector('#geotools')) {document.querySelector('#geotools').style.display = 'none';}
++ if (document.querySelector('#header')) {document.querySelector('#header').style.display = 'none';}
++ if (document.querySelector('#snapcontrol')) {document.querySelector('#snapcontrol').style.display = 'none';}
++ if (document.querySelectorAll('.img_snap')[0]) {document.querySelectorAll('.img_snap')[0].style.display = 'none';}
++ if (document.querySelector('#display_msg_text')) {document.querySelector('#display_msg_text').style.display = 'none';}
++ });
++ page.evaluate(function() {
++ var hide = document.querySelectorAll('.gmnoprint');
++ for (var index = 0; index < hide.length; ++index) {
++ hide[index].style.display = 'none';
++ }
++ });
+ }
+
+-/**
+- * Prepare map for screenshooting. Make screenshots same width and height with map_canvas
+- * If IITC, also set width and height
+- * @param {boolean} iitcz
+- * @param {number} widthz
+- * @param {number} heightz
+- */
+ function prepare(widthz, heightz, search) {
+- system.stdout.writeLine('prepare...');
+- if (search == "nix") {
+- var selector = "#map_canvas";
+- setElementBounds(selector);
+- }else{
+- page.evaluate(function(search) {
+- if (document.querySelector('#geocode')){
+- document.getElementById("address").value=search;
+- document.querySelector("input[value=Search]").click();
+- }
+- }, search);
+- var selector = "#map_canvas";
+- setElementBounds(selector);
+- }
++ if (search == "nix") {
++ var selector = "#map_canvas";
++ setElementBounds(selector);
++ }else{
++ page.evaluate(function(search) {
++ if (document.querySelector('#geocode')){
++ document.getElementById("address").value=search;
++ document.querySelector("input[value=Search]").click();
++ }
++ }, search);
++ var selector = "#map_canvas";
++ setElementBounds(selector);
++ }
+ }
+
+-/**
+- * Sets element bounds
+- * @param selector
+- */
+ function setElementBounds(selector) {
+ page.clipRect = page.evaluate(function(selector) {
+ var clipRect = document.querySelector(selector).getBoundingClientRect();
+@@ -197,10 +149,6 @@ function setElementBounds(selector) {
+ }, selector);
+ }
+
+-/**
+- * Checks if human presence not detected and makes a human present
+- * @since 2.3.0
+- */
+ function humanPresence() {
+ var outside = page.evaluate(function() {
+ return !!(document.getElementById('butterbar') && (document.getElementById('butterbar').style.display !== 'none'));
+@@ -247,37 +195,34 @@ function getDateTime(format) {
+ }
+
+ function addTimestamp(time) {
+- page.evaluate(function(dateTime) {
+- var water = document.createElement('p');
+- water.id='watermark-ice';
+- water.innerHTML = dateTime;
+- water.style.position = 'absolute';
+- water.style.color = 'orange';
+- water.style.top = '0';
+- water.style.left = '0';
+- water.style.fontSize = '40px';
+- water.style.opacity = '0.8';
+- water.style.marginTop = '0';
+- water.style.paddingTop = '0';
+- water.style.fontFamily = 'monospace';
+- water.style.textShadow = '2px 2px 5px #111717';
+- document.querySelector('#map_canvas').appendChild(water);
+- }, time);
++ page.evaluate(function(dateTime) {
++ var water = document.createElement('p');
++ water.id='watermark-ice';
++ water.innerHTML = dateTime;
++ water.style.position = 'absolute';
++ water.style.color = 'orange';
++ water.style.top = '0';
++ water.style.left = '0';
++ water.style.fontSize = '40px';
++ water.style.opacity = '0.8';
++ water.style.marginTop = '0';
++ water.style.paddingTop = '0';
++ water.style.fontFamily = 'monospace';
++ water.style.textShadow = '2px 2px 5px #111717';
++ document.querySelector('#map_canvas').appendChild(water);
++ }, time);
+ }
+
+ /**
+ * Main function.
+ */
+ function main() {
+- system.stdout.writeLine('main...');
+- if (true){
+- page.evaluate(function() {
+- if (document.getElementById('watermark-ice')) {
+- var oldStamp = document.getElementById('watermark-ice');
+- oldStamp.parentNode.removeChild(oldStamp);
+- }
+- });
+- }
++ page.evaluate(function() {
++ if (document.getElementById('watermark-ice')) {
++ var oldStamp = document.getElementById('watermark-ice');
++ oldStamp.parentNode.removeChild(oldStamp);
++ }
++ });
+ humanPresence();
+ window.setTimeout(function() {
+ addTimestamp(getDateTime(0));
diff --git a/pulls/1.json b/pulls/1.json
@@ -0,0 +1,18 @@
+{
+ "number": 1,
+ "title": "IITC",
+ "state": "merged",
+ "diff_file": "1.diff",
+ "author": "MTRNord",
+ "created_at": "2016-11-14T19:14:05Z",
+ "closed_at": "2016-11-14T19:14:17Z",
+ "merged_at": "2016-11-14T19:14:17Z",
+ "base_ref": "master",
+ "head_ref": "iitc",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "Add IITC and completely rework Repository\n\n<!-- Reviewable:start -->\n---\nThis change is\u2002[<img src=\"https://reviewable.io/review_button.svg\" height=\"34\" align=\"absmiddle\" alt=\"Reviewable\"/>](https://reviewable.io/reviews/mtrnord/intel-screenbot/1)\n<!-- Reviewable:end -->\n",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/1.md b/pulls/1.md
@@ -0,0 +1,19 @@
+# PR #1 IITC
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-11-14T19:14:05Z
+- **Branch:** iitc → master
+- **Merged:** 2016-11-14T19:14:17Z
+- **Diff:** [1.diff](./1.diff)
+
+---
+
+Add IITC and completely rework Repository
+
+<!-- Reviewable:start -->
+---
+This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/mtrnord/intel-screenbot/1)
+<!-- Reviewable:end -->
+
+
diff --git a/pulls/10.diff b/pulls/10.diff
@@ -0,0 +1,13 @@
+diff --git a/README.md b/README.md
+index 8e070d1..5328911 100644
+--- a/README.md
++++ b/README.md
+@@ -105,8 +105,3 @@ tar xvjf phantomjs-2.1.1-linux-x86_64.tar.bz2
+ mv phantomjs-2.1.1-linux-x86_64 /usr/local/share
+ ln -sf /usr/local/share/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin
+ ```
+-
+-# Sponsoring
+-<a target='_blank' rel='nofollow' href='https://app.codesponsor.io/link/pc1YAZAnXxNRhLY8PX5qJ9P3/MTRNord/intel_screenbot'>
+- <img alt='Sponsor' width='888' height='68' src='https://app.codesponsor.io/embed/pc1YAZAnXxNRhLY8PX5qJ9P3/MTRNord/intel_screenbot.svg' />
+-</a>
diff --git a/pulls/10.json b/pulls/10.json
@@ -0,0 +1,18 @@
+{
+ "number": 10,
+ "title": "remove codesponsor",
+ "state": "merged",
+ "diff_file": "10.diff",
+ "author": "itsjw",
+ "created_at": "2018-01-04T16:55:31Z",
+ "closed_at": "2018-01-04T16:56:45Z",
+ "merged_at": "2018-01-04T16:56:45Z",
+ "base_ref": "master",
+ "head_ref": "master",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "Pull request automatically sent by knewzen <https://github.com/knewzen>. Because Code Sponsor is shutting down on December 8",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/10.md b/pulls/10.md
@@ -0,0 +1,13 @@
+# PR #10 remove codesponsor
+
+- **Status:** merged
+- **Author:** @itsjw
+- **Created:** 2018-01-04T16:55:31Z
+- **Branch:** master → master
+- **Merged:** 2018-01-04T16:56:45Z
+- **Diff:** [10.diff](./10.diff)
+
+---
+
+Pull request automatically sent by knewzen <https://github.com/knewzen>. Because Code Sponsor is shutting down on December 8
+
diff --git a/pulls/2.diff b/pulls/2.diff
@@ -0,0 +1,1023 @@
+diff --git a/README.md b/README.md
+index 5dcbdb8..d6a6132 100644
+--- 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
+index e89abdc..49ecbcf 100644
+--- 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
+index 2648a61..39a0e12 100644
+--- 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
+index c9413db..6fa062a 100644
+--- 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<mpl='
++ 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
+index 3ef8afc..0696c0e 100644
+--- 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<mpl='
++
++ 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) {
diff --git a/pulls/2.json b/pulls/2.json
@@ -0,0 +1,22 @@
+{
+ "number": 2,
+ "title": "Email login",
+ "state": "merged",
+ "diff_file": "2.diff",
+ "author": "MTRNord",
+ "created_at": "2016-11-15T21:24:39Z",
+ "closed_at": "2016-11-19T01:00:55Z",
+ "merged_at": "2016-11-19T01:00:55Z",
+ "base_ref": "master",
+ "head_ref": "EmailLogin",
+ "labels": [
+ "enhancement"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "requested_reviewers": [],
+ "body": "",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/2.md b/pulls/2.md
@@ -0,0 +1,15 @@
+# PR #2 Email login
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-11-15T21:24:39Z
+- **Branch:** EmailLogin → master
+- **Merged:** 2016-11-19T01:00:55Z
+- **Labels:** enhancement
+- **Assignees:** @MTRNord
+- **Diff:** [2.diff](./2.diff)
+
+---
+
+_No description._
+
diff --git a/pulls/4.diff b/pulls/4.diff
@@ -0,0 +1,1079 @@
+diff --git a/__init__.py b/__init__.py
+index ace5c67..70cb1ff 100644
+--- a/__init__.py
++++ b/__init__.py
+@@ -86,31 +86,12 @@ def _get_lines(shell_command):
+ return p.returncode, output, True
+
+ @asyncio.coroutine
+-def _screencap(maptype, url, filepath, filename, SACSID, CSRF, plugins, search, bot, event):
++def _screencap(url, args_filepath, filepath, filename, bot, event):
+ loop = asyncio.get_event_loop()
+- logger.info("screencapping {} and saving as {}".format(url, filepath))
+- if plugins is '':
+- 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, 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, 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, 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, 420.0)
+- exitcode, output, status = yield from task
++ command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap.js "' + args_filepath + '"'
++ task = _get_lines(command)
++ 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)
+@@ -149,6 +130,8 @@ def intel(bot, event, *args):
+ """get a screenshot of a search term or intel URL or the default intel URL of the hangout.
+ """
+
++ arguments = {}
++
+ if args:
+ if len(args) > 1:
+ url = ' '.join(str(i) for i in args)
+@@ -159,22 +142,17 @@ def intel(bot, event, *args):
+ else:
+ url = bot.conversation_memory_get(event.conv_id, 'IntelURL')
+
+- if bot.config.exists(["intel_screenbot", "SACSID"]):
+- 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", "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"])
++ email = bot.config.get_by_path(["intel_screenbot", "email"])
++ password = bot.config.get_by_path(["intel_screenbot", "password"])
++ arguments['email'] = email
++ arguments['password'] = 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 SACSID Cookie or Email/password has been added to config. Unable to authenticate".format(event.user.full_name)
++ html = "<i><b>{}</b> No Intel 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:
+@@ -182,29 +160,53 @@ def intel(bot, event, *args):
+ yield from bot.coro_send_message(event.conv, html)
+
+ else:
+- if re.match(r'^[a-zA-Z]+://', url):
+- search = False
+- ZoomSearch = re.finditer(r"(?:&z=).*", url)
+- for matchNum, zoomlevel_raw in enumerate(ZoomSearch):
+- matchNum = matchNum + 1
+- zoomlevel_clean = zoomlevel_raw.group()
+- zoomlevel = zoomlevel_clean[3:][:2]
+- if zoomlevel.isdigit():
+- yield from bot.coro_send_message(event.conv_id, "<i>intel map at zoom level "+ zoomlevel + " requested, please wait...</i>")
++ if re.match(r'(http(s)?:\/\/)', url):
++ search = 'nix'
++ zoomParameter = re.search(r"(?:&z=)", url, re.IGNORECASE)
++ if zoomParameter:
++ ZoomSearch = re.finditer(r"(?:&z=).*", url, flags=re.I)
++ for matchNum, zoomlevel_raw in enumerate(ZoomSearch):
++ matchNum = matchNum + 1
++ zoomlevel_clean = zoomlevel_raw.group()
++ zoomlevel = zoomlevel_clean[3:][:2]
++ if zoomlevel.isdigit():
++ yield from bot.coro_send_message(event.conv_id, "<i>intel map at zoom level "+ zoomlevel + " requested, please wait...</i>")
+ else:
+ yield from bot.coro_send_message(event.conv_id, "<i>intel map at last zoom level requested, please wait...</i>")
+ else:
+ search = url
+- logger.info(search);
++ zoomParameter = re.search(r"(?<=z=)", url, re.IGNORECASE)
++ if zoomParameter:
++ ZoomSearch = re.finditer(r"(?<=z=)[^\s]+", url, flags=re.I)
++ for matchNum, zoomlevel_raw in enumerate(ZoomSearch):
++ matchNum = matchNum + 1
++ zoomlevel = zoomlevel_raw.group()
++ search = search.replace("z={}".format(zoomlevel),"")
++ if zoomlevel.isdigit():
++ yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting at zoom level "+ zoomlevel + " as requested, please wait...</i>")
++ arguments['zoomlevel'] = str(zoomlevel)
++ else:
++ yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting as requested, please wait...</i>")
+ 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>")
+
+ filepath = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name
+ filename = filepath.split('/', filepath.count('/'))[-1]
++ args_filepath = tempfile.NamedTemporaryFile(prefix="args_{}".format(event.conv_id), suffix=".json", delete=False).name
+ logger.debug("temporary screenshot file: {}".format(filepath))
++ logger.debug("temporary args file: {}".format(args_filepath))
++
++ arguments['search'] = search
++ arguments['url'] = url
++ arguments['filepath'] = filepath
++ arguments['maptype'] = "intel"
++
++ with open(args_filepath, 'w') as out:
++ out.write(json.dumps(arguments))
++
++
+ try:
+ loop = asyncio.get_event_loop()
+- image_data = yield from _screencap("intel", url, filepath, filename, SACSID, CSRF, "", search, bot, event)
++ image_data = yield from _screencap(url, args_filepath, filepath, filename, bot, event)
+ except Exception as e:
+ yield from bot.coro_send_message(event.conv_id, "<i>error getting screenshot</i>")
+ logger.exception("screencap failed".format(url))
+@@ -215,6 +217,8 @@ def iitc(bot, event, *args):
+ """get a screenshot of a search term or intel URL or the default intel URL of the hangout.
+ """
+
++ arguments = {}
++
+ if args:
+ if len(args) > 1:
+ url = ' '.join(str(i) for i in args)
+@@ -225,50 +229,58 @@ def iitc(bot, event, *args):
+ else:
+ url = bot.conversation_memory_get(event.conv_id, 'IntelURL')
+
+- if bot.config.exists(["intel_screenbot", "SACSID"]):
+- 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", "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"])
++ email = bot.config.get_by_path(["intel_screenbot", "email"])
++ password = bot.config.get_by_path(["intel_screenbot", "password"])
++ arguments['email'] = email
++ arguments['password'] = 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 SACSID Cookie or Email/password has been added to config. Unable to authenticate".format(event.user.full_name)
++ html = "<i><b>{}</b> No Intel 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)
+
+ else:
+- if re.match(r'^[a-zA-Z]+://', url):
+- search = False
+- ZoomSearch = re.finditer(r"(?:&z=).*", url)
+- for matchNum, zoomlevel_raw in enumerate(ZoomSearch):
+- matchNum = matchNum + 1
+- zoomlevel_clean = zoomlevel_raw.group()
+- zoomlevel = zoomlevel_clean[3:][:2]
+- if zoomlevel.isdigit():
+- yield from bot.coro_send_message(event.conv_id, "<i>intel map at zoom level "+ zoomlevel + " requested, please wait...</i>")
++ if re.match(r'(http(s)?:\/\/)', url):
++ search = 'nix'
++ zoomParameter = re.search(r"(?:&z=)", test_str, re.IGNORECASE)
++ if zoomParameter:
++ ZoomSearch = re.finditer(r"(?:&z=).*", url, flags=re.I)
++ for matchNum, zoomlevel_raw in enumerate(ZoomSearch):
++ matchNum = matchNum + 1
++ zoomlevel_clean = zoomlevel_raw.group()
++ zoomlevel = zoomlevel_clean[3:][:2]
++ if zoomlevel.isdigit():
++ yield from bot.coro_send_message(event.conv_id, "<i>intel map at zoom level "+ zoomlevel + " requested, please wait...</i>")
+ else:
+ yield from bot.coro_send_message(event.conv_id, "<i>intel map at last zoom level requested, please wait...</i>")
+ else:
+ search = url
+- logger.info(search);
++ zoomParameter = re.search(r"(?<=z=)", url, re.IGNORECASE)
++ if zoomParameter:
++ ZoomSearch = re.finditer(r"(?<=z=)[^\s]+", url, flags=re.I)
++ for matchNum, zoomlevel_raw in enumerate(ZoomSearch):
++ matchNum = matchNum + 1
++ zoomlevel = zoomlevel_raw.group()
++ search = search.replace("z={}".format(zoomlevel),"")
++ if zoomlevel.isdigit():
++ yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting at zoom level "+ zoomlevel + " as requested, please wait...</i>")
++ arguments['zoomlevel'] = str(zoomlevel)
++ else:
++ yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting as requested, please wait...</i>")
+ 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>")
+
+ 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
++ args_filepath = tempfile.NamedTemporaryFile(prefix="args_{}".format(event.conv_id), suffix=".json", delete=False).name
+ logger.debug("temporary screenshot file: {}".format(filepath))
++ logger.debug("temporary args file: {}".format(args_filepath))
+ if bot.conversation_memory_get(event.conv_id, 'iitc_plugins'):
+ plugins = []
+ plugin_names = bot.conversation_memory_get(event.conv_id, 'iitc_plugins').split(", ")
+@@ -280,12 +292,18 @@ def iitc(bot, event, *args):
+ else:
+ plugins = ''
+
+- with open(plugins_filepath, 'w') as out:
+- out.write(json.dumps(plugins))
++ arguments['plugins'] = plugins
++ arguments['search'] = search
++ arguments['url'] = url
++ arguments['filepath'] = filepath
++ arguments['maptype'] = "iitc"
++
++ with open(args_filepath, 'w') as out:
++ out.write(json.dumps(arguments))
+
+ try:
+ loop = asyncio.get_event_loop()
+- image_data = yield from _screencap("iitc", url, filepath, filename, SACSID, CSRF, plugins_filepath, search, bot, event)
++ image_data = yield from _screencap(url, args_filepath, filepath, filename, bot, event)
+ except Exception as e:
+ yield from bot.coro_send_message(event.conv_id, "<i>error getting screenshot</i>")
+ logger.exception("screencap failed".format(url))
+diff --git a/screencap_iitc.js b/screencap.js
+similarity index 72%
+rename from screencap_iitc.js
+rename to screencap.js
+index 6fa062a..83a260a 100644
+--- a/screencap_iitc.js
++++ b/screencap.js
+@@ -4,52 +4,39 @@ var page = require('webpage').create();
+ var fs = require('fs');
+ var cookiespath = '.iced_cookies';
+ var config = '';
++var loginTimeout = '5000';
+ if (args.length === 1) {
+ console.log('Try to pass some args when invoking this script!');
+ } else {
+- if (args.length === 6){
+- var SACSID = args[1];
+- var CSRF = args[2];
+- var IntelURL = args[3];
+- var filepath = args[4];
+- var plugins_file = args[5];
+- var search = 'nix';
+- var loginTimeout = '5000';
+- }else{
+- if (args.length === 7){
+- var SACSID = args[1];
+- var CSRF = args[2];
+- var IntelURL = args[3];
+- var filepath = args[4];
+- var search = args[5];
+- var plugins_file = args[6];
+- var loginTimeout = '5000';
+- }
++ var arguments_file = args[1];
++ var arguments = JSON.parse(fs.read(arguments_file));
++ if (arguments.hasOwnProperty('plugins')) {
++ var plugins = arguments["plugins"]
+ }
++ if (arguments.hasOwnProperty('zoomlevel')) {
++ var zoomlevel = arguments["zoomlevel"]
++ }
++ var maptype = arguments["maptype"]
++ var search = arguments["search"]
++ var url = arguments["url"]
++ var filepath = arguments['filepath']
++ var user = arguments['email']
++ var pass = arguments['password']
+ }
+-
+-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) {
++function quit() {
+ 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);
+-}
++
++loadCookies(function() {
++ if (config.SACSID == undefined || config.SACSID == '') {
++ firePlainLogin(user, pass, url);
++ } else {
++ addCookies(config.SACSID, config.CSRF);
++ console.log('Using cookies to log in');
++ afterCookieLogin(url, search);
++ }
++});
++
+
+ function loadCookies(callback) {
+ if(fs.exists(cookiespath)) {
+@@ -85,22 +72,21 @@ function storeCookies() {
+ }
+ }
+
+-function firePlainLogin(SACSID, CSRF) {
++function firePlainLogin(user, pass, url) {
+ page.open('https://www.ingress.com/intel', function (status) {
+ page.evaluate(function () {
+ localStorage.clear()
+ });
+- if (status !== 'success') {quit('unable to connect to remote server')}
++ if (status !== 'success') {console.log("Login ERROR"); quit();}
+ 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<mpl='
+ page.open(link, function () {
+- login(SACSID, CSRF);
++ login(user, pass, url);
+ });
+ });
+ }
+
+-function login(l, p) {
++function login(l, p, url) {
+ if (document.querySelector('#timeoutError')){
+- login(l, p)
+ firePlainLogin(l, p)
+ }
+ waitFor({
+@@ -136,7 +122,8 @@ function login(l, p) {
+ }
+ window.setTimeout(function () {
+ if (page.url.substring(0,40) === 'https://accounts.google.com/ServiceLogin') {
+- quit('login failed: wrong email and/or password');
++ console.log("login failed: wrong email and/or password")
++ quit()
+ }
+
+ if (page.url.substring(0,40) === 'https://appengine.google.com/_ah/loginfo') {
+@@ -149,39 +136,49 @@ function login(l, p) {
+ if (page.url.substring(0,44) === 'https://accounts.google.com/signin/challenge') {
+ twostep = system.stdin.readLine();
+ }
+- window.setTimeout(afterPlainLogin(IntelURL, search), loginTimeout);
++ window.setTimeout(afterPlainLogin(url, search), loginTimeout);
+ }, loginTimeout)
+ }, loginTimeout / 10);
+ },
+ error: function () {
++ console.log("error waitingFor loginform")
+ quit();
+ }
+ });
+ }
+
+-function afterPlainLogin(IntelURL, search) {
++function afterPlainLogin(url, search) {
+ page.viewportSize = { width: '1280', height: '720' };
+- page.open(IntelURL, function(status) {
+- if (status !== 'success') {quit('unable to connect to remote server')}
++ page.open(url, function(status) {
++ console.log(url)
++ if (status !== 'success') {console.log('unable to connect to remote server afterPlainLogin'); quit()}
+ if (!isSignedIn()) {
+ console.log("not logged in")
+ quit();
+ }
+ setTimeout(function() {
+- setupIITC()
++ storeCookies();
++ setupIITC()
+ setTimeout(function() {
+- setTimeout(function() {if (search != "nix") {searchfunc(search);}}, 1000);
++ 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;
+- }
+- });
++ return page.evaluate(function(zoomlevel) {
++ if (typeof zoomlevel === 'undefined' || zoomlevel === null) {
++ window.map.setZoom(zoomlevel,animate=false)
++ }
++ if (document.querySelector('.map').textContent.indexOf('done') != -1) {
++ return true;
++ }else{
++ console.log('generateFakeOutput')
++ return false;
++ }
++ }, zoomlevel);
+ },
+ success: function () {
+ var startTime = new Date().getTime();
+@@ -260,38 +257,33 @@ function loadLocalIitcPlugin(src) {
+ page.injectJs(src)
+ }
+
+-function afterCookieLogin(IntelURL, search) {
++function afterCookieLogin(url, search) {
+ page.viewportSize = { width: '1280', height: '720' };
+- page.open(IntelURL, function(status) {
++ page.open(url, 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.');
+- }
++ quit('Cookies are obsolete. Update your config file.');
+ }
+ setTimeout(function() {
+ setupIITC()
+ setTimeout(function() {
+- if (search != "nix") {searchfunc(search);}
++ if (search != "nix") {
++ searchfunc(search);
++ }
+ 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;
+- }
+- });
++ 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();
+@@ -326,7 +318,7 @@ function afterCookieLogin(IntelURL, search) {
+ }
+
+ function searchfunc(search){
+- page.evaluate(function(search) {
++ page.evaluate(function(search, zoomlevel) {
+ if (document.querySelector('#search')){
+ window.addHook('search', function(query) {
+ var checkExist = setInterval(function() {
+@@ -335,18 +327,22 @@ function searchfunc(search){
+ map.fitBounds(query.results[0].bounds, {maxZoom: 17})
+ clearInterval(checkExist);
+ }
++ if (typeof zoomlevel !== 'undefined' || zoomlevel !== null) {
++ console.log(zoomlevel)
++ window.map.setZoom(zoomlevel,animate=false)
++ }
+ }, 100);
+ });
+ setTimeout(function() {
+ window.search.doSearch(search, true)
+ }, 2000);
+ }
+- }, search);
++ }, search, zoomlevel);
+ }
+
+ function setupIITC(){
+ loadIitcPlugin('https://static.iitc.me/build/release/plugins/canvas-render.user.js');
+- page.evaluate(function() {
++ page.evaluate(function(maptype) {
+ localStorage['ingress.intelmap.layergroupdisplayed'] = JSON.stringify({
+ "Unclaimed Portals": true,
+ "Level 1 Portals": true,
+@@ -369,16 +365,22 @@ function setupIITC(){
+ 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);
++ if (maptype == "intel") {
++ localStorage['iitc-base-map'] = 'Google Default Ingress Map';
++ }else {
++ localStorage['iitc-base-map'] = 'Google Roads';
+ }
++ }, maptype);
++ if (maptype != "intel") {
++ console.log(plugins);
++ for(var i in plugins){
++ var plugin = plugins[i];
++ if(plugin.match('(http(s)?:\/\/)')){
++ loadIitcPlugin(plugin);
++ }else{
++ loadLocalIitcPlugin(plugin);
++ }
++ }
+ }
+ }
+
+@@ -390,7 +392,7 @@ function s(file) {
+ var interval = setInterval(function(){
+ if(new Date().getTime() - startTime > 5000){
+ clearInterval(interval);
+- phantom.exit(0);
++ quit();
+ return;
+ }
+ console.log('doSomeOutput')
+@@ -478,23 +480,43 @@ function getDateTime(format) {
+ }
+
+ function addTimestamp(time) {
+- page.evaluate(function(dateTime, search) {
+- var water = document.createElement('p');
+- water.id='watermark-ice';
+- water.innerHTML = dateTime + ' - ' + search;
+- water.style.position = 'absolute';
+- water.style.color = '#3A539B';
+- water.style.top = '0';
+- water.style.zIndex = '4404';
+- water.style.marginTop = '0';
+- water.style.paddingTop = '0';
+- water.style.left = '0';
+- water.style.fontSize = '40px';
+- water.style.opacity = '0.8';
+- water.style.fontFamily = 'monospace';
+- water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
+- document.querySelectorAll('body')[0].appendChild(water);
+- }, time, search);
++ if (maptype == "iitc") {
++ page.evaluate(function(dateTime, search) {
++ var water = document.createElement('p');
++ water.id='watermark-ice';
++ water.innerHTML = dateTime + ' - ' + search;
++ water.style.position = 'absolute';
++ water.style.color = '#3A539B';
++ water.style.top = '0';
++ water.style.zIndex = '4404';
++ water.style.marginTop = '0';
++ water.style.paddingTop = '0';
++ water.style.left = '0';
++ water.style.fontSize = '40px';
++ water.style.opacity = '0.8';
++ water.style.fontFamily = 'monospace';
++ water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
++ document.querySelectorAll('body')[0].appendChild(water);
++ }, time, search);
++ }else {
++ page.evaluate(function(dateTime, search) {
++ var water = document.createElement('p');
++ water.id='watermark-ice';
++ water.style.zIndex = '4404';
++ water.innerHTML = dateTime + ' - ' + search;
++ water.style.position = 'absolute';
++ water.style.color = 'orange';
++ water.style.top = '0';
++ water.style.left = '0';
++ water.style.fontSize = '40px';
++ water.style.opacity = '0.8';
++ water.style.marginTop = '0';
++ water.style.paddingTop = '0';
++ water.style.fontFamily = 'monospace';
++ water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
++ document.querySelectorAll('body')[0].appendChild(water);
++ }, time, search);
++ }
+ }
+
+ /**
+diff --git a/screencap_intel.js b/screencap_intel.js
+deleted file mode 100644
+index 0696c0e..0000000
+--- a/screencap_intel.js
++++ /dev/null
+@@ -1,438 +0,0 @@
+-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 {
+- if (args.length === 5){
+- var SACSID = args[1];
+- var CSRF = args[2];
+- var IntelURL = args[3];
+- var filepath = args[4];
+- var search = 'nix';
+- var loginTimeout = '10000';
+- }else{
+- if (args.length === 6){
+- var SACSID = args[1];
+- var CSRF = args[2];
+- var IntelURL = args[3];
+- var filepath = args[4];
+- var search = args[5];
+- var loginTimeout = '10000';
+- }
+- }
+-}
+-
+-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<mpl='
+-
+- 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({
+- name: 'SACSID',
+- value: sacsid,
+- domain: 'www.ingress.com',
+- path: '/',
+- httponly: true,
+- secure: true
+- });
+- phantom.addCookie({
+- name: 'csrftoken',
+- value: csrf,
+- domain: 'www.ingress.com',
+- path: '/'
+- });
+-}
+-
+-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);
+-}
+-
+-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: 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 s(file) {
+- page.render(file);
+- phantom.exit(0);
+-}
+-
+-function hideDebris() {
+- page.evaluate(function() {
+- if (document.querySelector('#comm')) {document.querySelector('#comm').style.display = 'none';}
+- if (document.querySelector('#player_stats')) {document.querySelector('#player_stats').style.display = 'none';}
+- if (document.querySelector('#game_stats')) {document.querySelector('#game_stats').style.display = 'none';}
+- if (document.querySelector('#geotools')) {document.querySelector('#geotools').style.display = 'none';}
+- if (document.querySelector('#header')) {document.querySelector('#header').style.display = 'none';}
+- if (document.querySelector('#snapcontrol')) {document.querySelector('#snapcontrol').style.display = 'none';}
+- if (document.querySelectorAll('.img_snap')[0]) {document.querySelectorAll('.img_snap')[0].style.display = 'none';}
+- if (document.querySelector('#display_msg_text')) {document.querySelector('#display_msg_text').style.display = 'none';}
+- });
+- page.evaluate(function() {
+- var hide = document.querySelectorAll('.gmnoprint');
+- for (var index = 0; index < hide.length; ++index) {
+- hide[index].style.display = 'none';
+- }
+- });
+-}
+-
+-function prepare(widthz, heightz, search) {
+- if (search == "nix") {
+- var selector = "#map_canvas";
+- setElementBounds(selector);
+- }else{
+- page.evaluate(function(search) {
+- if (document.querySelector('#geocode')){
+- document.getElementById("address").value=search;
+- document.querySelector("input[value=Search]").click();
+- }
+- }, search);
+- var selector = "#map_canvas";
+- setElementBounds(selector);
+- }
+-}
+-
+-function setElementBounds(selector) {
+- page.clipRect = page.evaluate(function(selector) {
+- var clipRect = document.querySelector(selector).getBoundingClientRect();
+- return {
+- top: clipRect.top,
+- left: clipRect.left,
+- width: clipRect.width,
+- height: clipRect.height
+- };
+- }, selector);
+-}
+-
+-function humanPresence() {
+- var outside = page.evaluate(function() {
+- return !!(document.getElementById('butterbar') && (document.getElementById('butterbar').style.display !== 'none'));
+- });
+- if (outside) {
+- var rekt = page.evaluate(function() {
+- return document.getElementById('butterbar').getBoundingClientRect();
+- });
+- page.sendEvent('click', rekt.left + rekt.width / 2, rekt.top + rekt.height / 2);
+- }
+-}
+-
+-function getDateTime(format) {
+- var now = new Date();
+- var year = now.getFullYear();
+- var month = now.getMonth()+1;
+- var day = now.getDate();
+- var hour = now.getHours();
+- var minute = now.getMinutes();
+- var second = now.getSeconds();
+- var timeZone = '';
+- if(month.toString().length === 1) {
+- month = '0' + month;
+- }
+- if(day.toString().length === 1) {
+- day = '0' + day;
+- }
+- if(hour.toString().length === 1) {
+- hour = '0' + hour;
+- }
+- if(minute.toString().length === 1) {
+- minute = '0' + minute;
+- }
+- if(second.toString().length === 1) {
+- second = '0' + second;
+- }
+- var dateTime;
+- if (format === 1) {
+- dateTime = year + '-' + month + '-' + day + '--' + hour + '-' + minute + '-' + second;
+- } else {
+- dateTime = day + '.' + month + '.' + year + ' ' + hour + ':' + minute + ':' + second + timeZone;
+- }
+- return dateTime;
+-}
+-
+-function addTimestamp(time) {
+- page.evaluate(function(dateTime) {
+- var water = document.createElement('p');
+- water.id='watermark-ice';
+- water.innerHTML = dateTime;
+- water.style.position = 'absolute';
+- water.style.color = 'orange';
+- water.style.top = '0';
+- water.style.left = '0';
+- water.style.fontSize = '40px';
+- water.style.opacity = '0.8';
+- water.style.marginTop = '0';
+- water.style.paddingTop = '0';
+- water.style.fontFamily = 'monospace';
+- water.style.textShadow = '2px 2px 5px #111717';
+- document.querySelector('#map_canvas').appendChild(water);
+- }, time);
+-}
+-
+-/**
+- * Main function.
+- */
+-function main() {
+- page.evaluate(function() {
+- if (document.getElementById('watermark-ice')) {
+- var oldStamp = document.getElementById('watermark-ice');
+- oldStamp.parentNode.removeChild(oldStamp);
+- }
+- });
+- humanPresence();
+- window.setTimeout(function() {
+- addTimestamp(getDateTime(0));
+- file = filepath;
+- s(file);
+- }, 5000);
+-}
diff --git a/pulls/4.json b/pulls/4.json
@@ -0,0 +1,18 @@
+{
+ "number": 4,
+ "title": "Intel to iitc",
+ "state": "merged",
+ "diff_file": "4.diff",
+ "author": "MTRNord",
+ "created_at": "2016-12-10T19:59:40Z",
+ "closed_at": "2016-12-10T19:59:44Z",
+ "merged_at": "2016-12-10T19:59:44Z",
+ "base_ref": "master",
+ "head_ref": "IntelToIITC",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "# Updates\r\n\r\n- intel command now uses also iitc (but without plugins and with default map background)\r\n- zoom is now availible with z=<zoomlevel>\r\n- __init__.py is now minified",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/4.md b/pulls/4.md
@@ -0,0 +1,17 @@
+# PR #4 Intel to iitc
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-12-10T19:59:40Z
+- **Branch:** IntelToIITC → master
+- **Merged:** 2016-12-10T19:59:44Z
+- **Diff:** [4.diff](./4.diff)
+
+---
+
+# Updates
+
+- intel command now uses also iitc (but without plugins and with default map background)
+- zoom is now availible with z=<zoomlevel>
+- __init__.py is now minified
+
diff --git a/pulls/5.diff b/pulls/5.diff
@@ -0,0 +1,792 @@
+diff --git a/__init__.py b/__init__.py
+index dfdebf0..e0bc4bb 100644
+--- a/__init__.py
++++ b/__init__.py
+@@ -1,13 +1,9 @@
+ from bs4 import BeautifulSoup
+ import requests
+ import json
+-import asyncio, io, logging, os, re, time, tempfile
+-import subprocess
++import asyncio, io, logging, os, tempfile
+ import plugins
+ import re
+-from asyncio import subprocess
+-from shutil import move
+-from os import remove, close
+
+ logger = logging.getLogger(__name__)
+
+@@ -20,13 +16,9 @@ def _initialise(bot):
+
+ @asyncio.coroutine
+ def _open_file(name):
+- logger.debug("opening screenshot file: {}".format(name))
+- statinfo = os.stat(name)
+- logger.info(statinfo.st_size)
+ return open(name, 'rb')
+
+ def _parse_onlineRepos(url, ext=''):
+- logger.debug("parsing github or gitlab or http(s)")
+ page = requests.get(url).text
+ if 'gitlab.com' in url:
+ files = []
+@@ -96,7 +88,6 @@ def _screencap(url, args_filepath, filepath, filename, bot, event):
+
+ # read the resulting file into a byte array
+ # yield from asyncio.sleep(10)
+- logger.info(filepath)
+ 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)
+@@ -107,6 +98,8 @@ def _screencap(url, args_filepath, filepath, filename, bot, event):
+ os.unlink(filepath)
+ os.unlink(args_filepath)
+ except Exception as e:
++ os.unlink(filepath)
++ os.unlink(args_filepath)
+ 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>")
+@@ -114,8 +107,8 @@ def _screencap(url, args_filepath, filepath, filename, bot, event):
+
+ def setintel(bot, event, *args):
+ """set url for current converation for the intel or iitc command.
+- use /bot clearintel to clear the previous url before setting a new one.
+- """
++ use /bot clearintel to clear the previous url before setting a new one."""
++
+ url = bot.conversation_memory_get(event.conv_id, 'IntelURL')
+ if url is None:
+ bot.conversation_memory_set(event.conv_id, 'IntelURL', ''.join(args))
+@@ -130,8 +123,7 @@ def setintel(bot, event, *args):
+
+
+ def intel(bot, event, *args):
+- """get a screenshot of a search term or intel URL or the default intel URL of the hangout.
+- """
++ """get a screenshot of a search term or intel URL or the default intel URL of the hangout."""
+
+ arguments = {}
+
+@@ -143,7 +135,10 @@ def intel(bot, event, *args):
+ if '"' in url:
+ url = url.replace('"', '')
+ else:
+- url = bot.conversation_memory_get(event.conv_id, 'IntelURL')
++ try:
++ url = bot.conversation_memory_get(event.conv_id, 'IntelURL')
++ except:
++ url = 'https://www.ingress.com/intel'
+
+ if bot.config.exists(["intel_screenbot", "email"]):
+ if bot.config.exists(["intel_screenbot", "password"]):
+@@ -175,7 +170,7 @@ def intel(bot, event, *args):
+ if zoomlevel.isdigit():
+ yield from bot.coro_send_message(event.conv_id, "<i>intel map at zoom level "+ zoomlevel + " requested, please wait...</i>")
+ else:
+- yield from bot.coro_send_message(event.conv_id, "<i>intel map at last zoom level requested, please wait...</i>")
++ yield from bot.coro_send_message(event.conv_id, "<i>intel map requested, please wait...</i>")
+ else:
+ search = url
+ zoomParameter = re.search(r"(?<=z=)", url, re.IGNORECASE)
+@@ -186,17 +181,15 @@ def intel(bot, event, *args):
+ zoomlevel = zoomlevel_raw.group()
+ search = search.replace("z={}".format(zoomlevel),"")
+ if zoomlevel.isdigit():
+- yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting at zoom level "+ zoomlevel + " as requested, please wait...</i>")
++ yield from bot.coro_send_message(event.conv_id, "<i>searching " + search + " on intel map and screenshooting at zoom level "+ zoomlevel + " as requested, please wait...</i>")
+ arguments['zoomlevel'] = str(zoomlevel)
+ else:
+- yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting as requested, please wait...</i>")
++ yield from bot.coro_send_message(event.conv_id, "<i>searching " + search + " on intel map and screenshooting as requested, please wait...</i>")
+ url = 'https://www.ingress.com/intel'
+
+ filepath = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name
+ filename = filepath.split('/', filepath.count('/'))[-1]
+ args_filepath = tempfile.NamedTemporaryFile(prefix="args_{}".format(event.conv_id), suffix=".json", delete=False).name
+- logger.debug("temporary screenshot file: {}".format(filepath))
+- logger.debug("temporary args file: {}".format(args_filepath))
+
+ arguments['search'] = search
+ arguments['url'] = url
+@@ -205,8 +198,7 @@ def intel(bot, event, *args):
+
+ with open(args_filepath, 'w') as out:
+ out.write(json.dumps(arguments))
+-
+-
++
+ try:
+ loop = asyncio.get_event_loop()
+ image_data = yield from _screencap(url, args_filepath, filepath, filename, bot, event)
+@@ -217,8 +209,7 @@ def intel(bot, event, *args):
+
+
+ def iitc(bot, event, *args):
+- """get a screenshot of a search term or intel URL or the default intel URL of the hangout.
+- """
++ """get a screenshot of a search term or intel URL or the default intel URL of the hangout."""
+
+ arguments = {}
+
+@@ -260,9 +251,9 @@ def iitc(bot, event, *args):
+ zoomlevel_clean = zoomlevel_raw.group()
+ zoomlevel = zoomlevel_clean[3:][:2]
+ if zoomlevel.isdigit():
+- yield from bot.coro_send_message(event.conv_id, "<i>intel map at zoom level "+ zoomlevel + " requested, please wait...</i>")
++ yield from bot.coro_send_message(event.conv_id, "<i>iitc map at zoom level "+ zoomlevel + " requested, please wait...</i>")
+ else:
+- yield from bot.coro_send_message(event.conv_id, "<i>intel map at last zoom level requested, please wait...</i>")
++ yield from bot.coro_send_message(event.conv_id, "<i>iitc map requested, please wait...</i>")
+ else:
+ search = url
+ zoomParameter = re.search(r"(?<=z=)", url, re.IGNORECASE)
+@@ -273,10 +264,10 @@ def iitc(bot, event, *args):
+ zoomlevel = zoomlevel_raw.group()
+ search = search.replace("z={}".format(zoomlevel),"")
+ if zoomlevel.isdigit():
+- yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting at zoom level "+ zoomlevel + " as requested, please wait...</i>")
++ yield from bot.coro_send_message(event.conv_id, "<i>searching " + search + " on iitc map and screenshooting it at zoom level "+ zoomlevel + " as requested, please wait...</i>")
+ arguments['zoomlevel'] = str(zoomlevel)
+ else:
+- yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting as requested, please wait...</i>")
++ yield from bot.coro_send_message(event.conv_id, "<i>searching " + search + " on iitc map and and screenshooting it as requested, please wait...</i>")
+ url = 'https://www.ingress.com/intel'
+
+ filepath = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name
+@@ -313,6 +304,7 @@ def iitc(bot, event, *args):
+ return
+
+ def show_iitcplugins(bot, event, *args):
++ """Shows all available iitc Plugins."""
+ if bot.memory.exists(["iitc_plugins"]):
+ plugin_names = []
+ for plugin_objects in bot.memory.get_by_path(["iitc_plugins"]):
+@@ -322,6 +314,7 @@ def show_iitcplugins(bot, event, *args):
+ yield from bot.coro_send_to_user_and_conversation(event.user.id_.chat_id, event.conv_id, "<i><b>IITC Plugins:</b><br> {}</i>".format(', <br>'.join(str(i) for i in plugin_names)), _("<i><b>{}</b>, I've sent you the plugins ;)</i>").format(event.user.full_name))
+
+ def set_iitcplugins(bot, event, *args):
++ """sets the activated iitc plugins for a hangout."""
+ if not bot.conversation_memory_get(event.conv_id, 'iitc_plugins') is None:
+ bot.conversation_memory_set(event.conv_id, 'iitc_plugins', None)
+ bot.conversation_memory_set(event.conv_id, 'iitc_plugins', ', '.join(args))
+@@ -333,10 +326,10 @@ def set_iitcplugins(bot, event, *args):
+ yield from bot.coro_send_message(event.conv, html)
+
+ def active_iitcplugins(bot, event, *args):
++ """shows the activated iitc plugins for a hangout."""
+ if bot.conversation_memory_get(event.conv_id, 'iitc_plugins') is None:
+ html = "<i><b>{}</b> no active IITC Plugins for this conversation".format(event.user.full_name)
+ yield from bot.coro_send_message(event.conv, html)
+-
+ else:
+ plugins = bot.conversation_memory_get(event.conv_id, 'iitc_plugins')
+ html = "<i><b>{}</b> plugins for this conversation: {}<br />".format(event.user.full_name, plugins)
+diff --git a/screencap.js b/screencap.js
+index 30f8030..0b34349 100644
+--- a/screencap.js
++++ b/screencap.js
+@@ -23,20 +23,6 @@ if (args.length === 1) {
+ var user = arguments['email']
+ var pass = arguments['password']
+ }
+-function quit() {
+- phantom.exit(0);
+-}
+-
+-loadCookies(function() {
+- if (config.SACSID == undefined || config.SACSID == '') {
+- firePlainLogin(user, pass, url);
+- } else {
+- addCookies(config.SACSID, config.CSRF);
+- console.log('Using cookies to log in');
+- afterCookieLogin(url, search);
+- }
+-});
+-
+
+ function loadCookies(callback) {
+ if(fs.exists(cookiespath)) {
+@@ -58,6 +44,45 @@ function loadCookies(callback) {
+ callback();
+ }
+
++function addCookies(sacsid, csrf) {
++ phantom.addCookie({
++ name: 'SACSID',
++ value: sacsid,
++ domain: 'www.ingress.com',
++ path: '/',
++ httponly: true,
++ secure: true
++ });
++ phantom.addCookie({
++ name: 'csrftoken',
++ value: csrf,
++ domain: 'www.ingress.com',
++ path: '/'
++ });
++}
++
++loadCookies(function() {
++ if (config.SACSID == undefined || config.SACSID == '') {
++ firePlainLogin(user, pass, url);
++ } else {
++ addCookies(config.SACSID, config.CSRF);
++ afterLogin(url, search, "cookie");
++ }
++});
++
++function waitFor ($config) {
++ $config._start = $config._start || new Date();
++ if ($config.timeout && new Date - $config._start > $config.timeout) {
++ if ($config.error) $config.error();
++ return;
++ }
++ if ($config.check()) {
++ return $config.success();
++ }
++ setTimeout(waitFor, $config.interval || 0, $config);
++}
++
++
+ function isSignedIn() {
+ return page.evaluate(function() {
+ return document.getElementsByTagName('a')[0].innerText.trim() !== 'Sign in';
+@@ -77,7 +102,7 @@ function firePlainLogin(user, pass, url) {
+ page.evaluate(function () {
+ localStorage.clear()
+ });
+- if (status !== 'success') {console.log("Login ERROR"); quit();}
++ if (status !== 'success') {console.log("Login ERROR"); phantom.exit(0);}
+ 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<mpl='
+ page.open(link, function () {
+ login(user, pass, url);
+@@ -123,7 +148,7 @@ function login(l, p, url) {
+ window.setTimeout(function () {
+ if (page.url.substring(0,40) === 'https://accounts.google.com/ServiceLogin') {
+ console.log("login failed: wrong email and/or password")
+- quit()
++ phantom.exit(0);
+ }
+
+ if (page.url.substring(0,40) === 'https://appengine.google.com/_ah/loginfo') {
+@@ -136,114 +161,83 @@ function login(l, p, url) {
+ if (page.url.substring(0,44) === 'https://accounts.google.com/signin/challenge') {
+ twostep = system.stdin.readLine();
+ }
+- window.setTimeout(afterPlainLogin(url, search), loginTimeout);
++ window.setTimeout(afterLogin(url, search, "plain"), loginTimeout);
+ }, loginTimeout)
+ }, loginTimeout / 10);
+ },
+ error: function () {
+- console.log("error waitingFor loginform")
+- quit();
++ phantom.exit(0);
+ }
+ });
+ }
+
+-function afterPlainLogin(url, search) {
++function afterLogin(url, search, mode) {
+ page.viewportSize = { width: '1280', height: '720' };
+ page.open(url, function(status) {
+ console.log(url)
+- if (status !== 'success') {console.log('unable to connect to remote server afterPlainLogin'); quit()}
++ if (status !== 'success') {console.log('unable to connect to remote server afterPlainLogin'); phantom.exit(0);}
+ if (!isSignedIn()) {
++ if(mode =="cookie"){
++ if(fs.exists(cookiespath)) {
++ fs.remove(cookiespath);
++ }
++ }
+ console.log("not logged in")
+ quit();
+ }
+ setTimeout(function() {
+- storeCookies();
+- setupIITC()
+- setTimeout(function() {
+- setTimeout(function() {
+- if (search != 'nix') {
+- searchfunc(search);
+- }
+- }, 1000);
+- waitFor({
+- timeout: 240000,
+- check: function () {
+- return page.evaluate(function(zoomlevel) {
+- if (typeof zoomlevel === 'undefined' || zoomlevel === null) {
+- window.map.setZoom(zoomlevel,animate=false)
+- }
+- if (document.querySelector('.map').textContent.indexOf('done') != -1) {
+- return true;
+- }else{
+- console.log('generateFakeOutput')
+- return false;
+- }
+- }, zoomlevel);
+- },
+- 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");
++ if(mode == "plain"){
++ storeCookies();
++ }
++ setupIITC()
++ setTimeout(function() {
++ if (search != 'nix') {
++ searchfunc(search);
++ }
++ waitFor({
++ timeout: 240000,
++ check: function () {
++ return page.evaluate(function(zoomlevel) {
++ if (document.querySelector('.map').textContent.indexOf('done') != -1) {
++ return true;
++ }else{
++ console.log('generateFakeOutput')
++ return false;
++ }
++ }, zoomlevel);
++ },
++ 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',
+- value: sacsid,
+- domain: 'www.ingress.com',
+- path: '/',
+- httponly: true,
+- secure: true
+- });
+- phantom.addCookie({
+- name: 'csrftoken',
+- value: csrf,
+- domain: 'www.ingress.com',
+- path: '/'
+- });
+-}
+-
+-
+-function waitFor ($config) {
+- $config._start = $config._start || new Date();
+- if ($config.timeout && new Date - $config._start > $config.timeout) {
+- if ($config.error) $config.error();
+- return;
+- }
+- if ($config.check()) {
+- return $config.success();
+- }
+- setTimeout(waitFor, $config.interval || 0, $config);
+-}
+-
+ function loadIitcPlugin(src) {
+ page.evaluate(function(src) {
+ var script = document.createElement('script');
+@@ -257,82 +251,21 @@ function loadLocalIitcPlugin(src) {
+ page.injectJs(src)
+ }
+
+-function afterCookieLogin(url, search) {
+- page.viewportSize = { width: '1280', height: '720' };
+- page.open(url, function(status) {
+- if (status !== 'success') {quit('unable to connect to remote server')}
+- if(!isSignedIn()) {
+- if(fs.exists(cookiespath)) {
+- fs.remove(cookiespath);
+- }
+- quit('Cookies are obsolete. Update your config file.');
+- }
+- setTimeout(function() {
+- setupIITC()
+- setTimeout(function() {
+- if (search != "nix") {
+- searchfunc(search);
+- }
+- 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 searchfunc(search){
+ page.evaluate(function(search, zoomlevel) {
+ 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);
+- }
+- if (typeof zoomlevel !== 'undefined' || zoomlevel !== null) {
+- console.log(zoomlevel)
+- window.map.setZoom(zoomlevel,animate=false)
+- }
+- }, 100);
+- });
++ window.addHook('search', function(query) {
++ var checkExist = setInterval(function() {
++ if (query.results.length > 0) {
++ map.fitBounds(query.results[0].bounds, {maxZoom: 17})
++ clearInterval(checkExist);
++ }
++ if (typeof zoomlevel !== 'undefined' || zoomlevel !== null) {
++ console.log(zoomlevel)
++ window.map.setZoom(zoomlevel,animate=false)
++ }
++ }, 100);
++ });
+ setTimeout(function() {
+ window.search.doSearch(search, true)
+ }, 2000);
+@@ -341,47 +274,46 @@ function searchfunc(search){
+ }
+
+ function setupIITC(){
+- loadIitcPlugin('https://static.iitc.me/build/release/plugins/canvas-render.user.js');
+- page.evaluate(function(maptype) {
+- 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);
+- if (maptype == "intel") {
+- localStorage['iitc-base-map'] = 'Google Default Ingress Map';
+- }else {
+- localStorage['iitc-base-map'] = 'Google Roads';
+- }
+- }, maptype);
+- if (maptype != "intel") {
+- console.log(plugins);
+- for(var i in plugins){
+- var plugin = plugins[i];
+- if(plugin.match('(http(s)?:\/\/)')){
+- loadIitcPlugin(plugin);
+- }else{
+- loadLocalIitcPlugin(plugin);
+- }
++ loadIitcPlugin('https://static.iitc.me/build/release/plugins/canvas-render.user.js');
++ page.evaluate(function(maptype) {
++ localStorage['ingress.intelmap.layergroupdisplayed'] = JSON.stringify({
++ "Unclaimed Portals": false,
++ "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);
++ if (maptype == "intel") {
++ localStorage['iitc-base-map'] = 'Google Default Ingress Map';
++ }else {
++ localStorage['iitc-base-map'] = 'Google Roads';
++ }
++ }, maptype);
++ if (maptype != "intel") {
++ for(var i in plugins){
++ var plugin = plugins[i];
++ if(plugin.match('(http(s)?:\/\/)')){
++ loadIitcPlugin(plugin);
++ }else{
++ loadLocalIitcPlugin(plugin);
+ }
+ }
++ }
+ }
+
+ function s(file) {
+@@ -392,7 +324,7 @@ function s(file) {
+ var interval = setInterval(function(){
+ if(new Date().getTime() - startTime > 5000){
+ clearInterval(interval);
+- quit();
++ phantom.exit(0);
+ return;
+ }
+ console.log('doSomeOutput')
+@@ -481,81 +413,81 @@ function getDateTime(format) {
+
+ function addTimestamp(time) {
+ if (search == "nix") {
+- if (maptype == "iitc") {
+- page.evaluate(function(dateTime, search) {
+- var water = document.createElement('p');
+- water.id='watermark-ice';
+- water.innerHTML = dateTime;
+- water.style.position = 'absolute';
+- water.style.color = '#3A539B';
+- water.style.top = '0';
+- water.style.zIndex = '4404';
+- water.style.marginTop = '0';
+- water.style.paddingTop = '0';
+- water.style.left = '0';
+- water.style.fontSize = '40px';
+- water.style.opacity = '0.8';
+- water.style.fontFamily = 'monospace';
+- water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
+- document.querySelectorAll('body')[0].appendChild(water);
+- }, time, search);
+- }else {
+- page.evaluate(function(dateTime, search) {
+- var water = document.createElement('p');
+- water.id='watermark-ice';
+- water.style.zIndex = '4404';
+- water.innerHTML = dateTime;
+- water.style.position = 'absolute';
+- water.style.color = 'orange';
+- water.style.top = '0';
+- water.style.left = '0';
+- water.style.fontSize = '40px';
+- water.style.opacity = '0.8';
+- water.style.marginTop = '0';
+- water.style.paddingTop = '0';
+- water.style.fontFamily = 'monospace';
+- water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
+- document.querySelectorAll('body')[0].appendChild(water);
+- }, time, search);
+- }
++ if (maptype == "iitc") {
++ page.evaluate(function(dateTime, search) {
++ var water = document.createElement('p');
++ water.id='watermark-ice';
++ water.innerHTML = dateTime;
++ water.style.position = 'absolute';
++ water.style.color = '#3A539B';
++ water.style.top = '0';
++ water.style.zIndex = '4404';
++ water.style.marginTop = '0';
++ water.style.paddingTop = '0';
++ water.style.left = '0';
++ water.style.fontSize = '30px';
++ water.style.opacity = '0.8';
++ water.style.fontFamily = 'monospace';
++ water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
++ document.querySelectorAll('body')[0].appendChild(water);
++ }, time, search);
++ }else {
++ page.evaluate(function(dateTime, search) {
++ var water = document.createElement('p');
++ water.id='watermark-ice';
++ water.style.zIndex = '4404';
++ water.innerHTML = dateTime;
++ water.style.position = 'absolute';
++ water.style.color = 'orange';
++ water.style.top = '0';
++ water.style.left = '0';
++ water.style.fontSize = '30px';
++ water.style.opacity = '0.8';
++ water.style.marginTop = '0';
++ water.style.paddingTop = '0';
++ water.style.fontFamily = 'monospace';
++ water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
++ document.querySelectorAll('body')[0].appendChild(water);
++ }, time, search);
++ }
+ }else{
+- if (maptype == "iitc") {
+- page.evaluate(function(dateTime, search) {
+- var water = document.createElement('p');
+- water.id='watermark-ice';
+- water.innerHTML = dateTime + ' - ' + search;
+- water.style.position = 'absolute';
+- water.style.color = '#3A539B';
+- water.style.top = '0';
+- water.style.zIndex = '4404';
+- water.style.marginTop = '0';
+- water.style.paddingTop = '0';
+- water.style.left = '0';
+- water.style.fontSize = '40px';
+- water.style.opacity = '0.8';
+- water.style.fontFamily = 'monospace';
+- water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
+- document.querySelectorAll('body')[0].appendChild(water);
+- }, time, search);
+- }else {
+- page.evaluate(function(dateTime, search) {
+- var water = document.createElement('p');
+- water.id='watermark-ice';
+- water.style.zIndex = '4404';
+- water.innerHTML = dateTime + ' - ' + search;
+- water.style.position = 'absolute';
+- water.style.color = 'orange';
+- water.style.top = '0';
+- water.style.left = '0';
+- water.style.fontSize = '40px';
+- water.style.opacity = '0.8';
+- water.style.marginTop = '0';
+- water.style.paddingTop = '0';
+- water.style.fontFamily = 'monospace';
+- water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
+- document.querySelectorAll('body')[0].appendChild(water);
+- }, time, search);
+- }
++ if (maptype == "iitc") {
++ page.evaluate(function(dateTime, search) {
++ var water = document.createElement('p');
++ water.id='watermark-ice';
++ water.innerHTML = dateTime + ' - ' + search;
++ water.style.position = 'absolute';
++ water.style.color = '#3A539B';
++ water.style.top = '0';
++ water.style.zIndex = '4404';
++ water.style.marginTop = '0';
++ water.style.paddingTop = '0';
++ water.style.left = '0';
++ water.style.fontSize = '30px';
++ water.style.opacity = '0.8';
++ water.style.fontFamily = 'monospace';
++ water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
++ document.querySelectorAll('body')[0].appendChild(water);
++ }, time, search);
++ }else {
++ page.evaluate(function(dateTime, search) {
++ var water = document.createElement('p');
++ water.id='watermark-ice';
++ water.style.zIndex = '4404';
++ water.innerHTML = dateTime + ' - ' + search;
++ water.style.position = 'absolute';
++ water.style.color = 'orange';
++ water.style.top = '0';
++ water.style.left = '0';
++ water.style.fontSize = '30px';
++ water.style.opacity = '0.8';
++ water.style.marginTop = '0';
++ water.style.paddingTop = '0';
++ water.style.fontFamily = 'monospace';
++ water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
++ document.querySelectorAll('body')[0].appendChild(water);
++ }, time, search);
++ }
+ }
+ }
+
diff --git a/pulls/5.json b/pulls/5.json
@@ -0,0 +1,18 @@
+{
+ "number": 5,
+ "title": "Code refactoring",
+ "state": "merged",
+ "diff_file": "5.diff",
+ "author": "MTRNord",
+ "created_at": "2016-12-31T19:03:27Z",
+ "closed_at": "2016-12-31T19:03:32Z",
+ "merged_at": "2016-12-31T19:03:32Z",
+ "base_ref": "master",
+ "head_ref": "CodeRefactoring",
+ "labels": [],
+ "assignees": [],
+ "requested_reviewers": [],
+ "body": "",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/5.md b/pulls/5.md
@@ -0,0 +1,13 @@
+# PR #5 Code refactoring
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2016-12-31T19:03:27Z
+- **Branch:** CodeRefactoring → master
+- **Merged:** 2016-12-31T19:03:32Z
+- **Diff:** [5.diff](./5.diff)
+
+---
+
+_No description._
+
diff --git a/pulls/7.diff b/pulls/7.diff
@@ -0,0 +1,579 @@
+diff --git a/README.md b/README.md
+index 52bd897..dcee288 100644
+--- a/README.md
++++ b/README.md
+@@ -19,10 +19,10 @@ To install the plugin you need to:
+
+ ## 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**
++**IMPORTANT: DO NOT USE YOUR MAIN ACCOUNT! I AM NOT RESPONSIBLE IF YOUR 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:
++*Note: DON'T set cookies up when using email/password*<br \><br \>
++For using the Intel Screenbot you need to add the following json-code to the config.json:
+
+ ```
+ "intel_screenbot": {
+@@ -34,8 +34,8 @@ For using the Intel Screenbot you need to add the following to the config.json:
+ }
+ ```
+
+-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)
++According to the official INSTALL Documention of the hangoutbot you will find the config.json in `/<username>/.local/share/hangupsbot/` <br \>
++(NOTE! add an comma behind the last element of the config.json and add it before the outer element closes)
+
+ Also you need to add `intel_screenbot` to the plugins.
+
+@@ -86,9 +86,15 @@ Also you need to add `intel_screenbot` to the plugins.
+ * If no `<url>` is supplied, use the default screenshot URL (or reply with an error if no URL is set)
+ * `z=` lets you change the zoomlevel of the map
+
++`/portalpic <url>`
++* Makes a screenshot of the Portalinfo of the defined portal.
++
++`/portalinfo <url>`
++* Gives you a text version of the most important Portal Information. (Pretty long!)
++
+ ## PhantomJS Installation
+
+-Only tested:
++Only tested way to install:
+
+ ```
+ wget https://cnpmjs.org/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
+diff --git a/__init__.py b/__init__.py
+index 50f1b24..8f83b12 100644
+--- a/__init__.py
++++ b/__init__.py
+@@ -9,14 +9,21 @@
+
+
+ def _initialise(bot):
+- plugins.register_user_command(["intel", "iitc", "active_iitcplugins"])
++ plugins.register_user_command(["intel", "iitc", "portalpic", "portalinfo", "active_iitcplugins"])
+ plugins.register_admin_command(["setintel", "show_iitcplugins", "set_iitcplugins"])
+ _get_iitc_plugins(bot)
+
+
+ @asyncio.coroutine
+-def _open_file(name):
+- return open(name, 'rb')
++def _open_file(name, otype):
++ return open(name, otype)
++
++@asyncio.coroutine
++def readline(f):
++ while True:
++ data = f.readline()
++ if data:
++ return data
+
+ def _parse_onlineRepos(url, ext=''):
+ page = requests.get(url).text
+@@ -78,7 +85,7 @@ def _get_lines(shell_command):
+ return p.returncode, output, True
+
+ @asyncio.coroutine
+-def _screencap(url, args_filepath, filepath, filename, bot, event):
++def _screencap(url, args_filepath, filepath, filename, bot, event, arguments):
+ os.chmod(filepath, 0o666)
+ loop = asyncio.get_event_loop()
+ command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap.js "' + args_filepath + '"'
+@@ -88,22 +95,30 @@ def _screencap(url, args_filepath, filepath, filename, bot, event):
+
+ # 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)
+- if status:
+- try:
+- image_id = yield from bot._client.upload_image(image_data, filename=filename)
+- yield from bot.coro_send_message(event.conv.id_, None, image_id=image_id)
+- os.unlink(filepath)
+- os.unlink(args_filepath)
+- except Exception as e:
++ if (arguments['screenshotfunction'] != 'portalinfoText'):
++ file_resource = yield from _open_file(filepath, 'rb')
++ 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)
++ if status:
++ try:
++ image_id = yield from bot._client.upload_image(image_data, filename=filename)
++ yield from bot.coro_send_message(event.conv.id_, None, image_id=image_id)
++ os.unlink(filepath)
++ os.unlink(args_filepath)
++ except Exception as e:
++ os.unlink(filepath)
++ os.unlink(args_filepath)
++ 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>")
++ else:
++ if status:
++ response_file = yield from _open_file(arguments['portalinfoResponse'], 'r')
++ response = yield from readline(response_file)
++ yield from bot.coro_send_message(event.conv.id_, response.replace("'", ""))
+ os.unlink(filepath)
+ os.unlink(args_filepath)
+- 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>")
+-
++ os.unlink(arguments['portalinfoResponse'])
+
+ def setintel(bot, event, *args):
+ """set url for current converation for the intel or iitc command.
+@@ -121,7 +136,122 @@ def setintel(bot, event, *args):
+ html = "<i><b>{}</b> updated screenshot URL".format(event.user.full_name)
+ yield from bot.coro_send_message(event.conv, html)
+
++def portalpic(bot, event, *args):
++ """get a screenshot of the portalInfo by URL."""
++
++ arguments = {}
+
++ if args:
++ if len(args) > 1:
++ url = ' '.join(str(i) for i in args)
++ else:
++ url = args[0]
++ if '"' in url:
++ url = url.replace('"', '')
++ else:
++ html = "<i><b>{}</b> No Arguments provided".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++
++ if bot.config.exists(["intel_screenbot", "email"]):
++ if bot.config.exists(["intel_screenbot", "password"]):
++ email = bot.config.get_by_path(["intel_screenbot", "email"])
++ password = bot.config.get_by_path(["intel_screenbot", "password"])
++ arguments['email'] = email
++ arguments['password'] = 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 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 Portal URL has been set for screenshots.".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++ else:
++ if re.match(r'(http(s)?:\/\/)', url):
++ yield from bot.coro_send_message(event.conv_id, "<i>Portal Info requested, please wait...</i>")
++ filepath = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name
++ filename = filepath.split('/', filepath.count('/'))[-1]
++ args_filepath = tempfile.NamedTemporaryFile(prefix="args_{}".format(event.conv_id), suffix=".json", delete=False).name
++
++ arguments['url'] = url
++ arguments['filepath'] = filepath
++ arguments['screenshotfunction'] = "portalinfoScreen"
++
++ with open(args_filepath, 'w') as out:
++ out.write(json.dumps(arguments))
++
++ try:
++ loop = asyncio.get_event_loop()
++ image_data = yield from _screencap(url, args_filepath, filepath, filename, bot, event)
++ except Exception as e:
++ yield from bot.coro_send_message(event.conv_id, "<i>error getting screenshot</i>")
++ logger.exception("screencap failed".format(url))
++ return
++ else:
++ html = "<i><b>{}</b> No URL found in Arguments".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++
++def portalinfo(bot, event, *args):
++ """get a of the portalInfo by URL."""
++
++ arguments = {}
++
++ if args:
++ if len(args) > 1:
++ url = ' '.join(str(i) for i in args)
++ else:
++ url = args[0]
++ if '"' in url:
++ url = url.replace('"', '')
++ else:
++ html = "<i><b>{}</b> No Arguments provided".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++
++ if bot.config.exists(["intel_screenbot", "email"]):
++ if bot.config.exists(["intel_screenbot", "password"]):
++ email = bot.config.get_by_path(["intel_screenbot", "email"])
++ password = bot.config.get_by_path(["intel_screenbot", "password"])
++ arguments['email'] = email
++ arguments['password'] = 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 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 Portal URL has been set for portal Info.".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++ else:
++ if re.match(r'(http(s)?:\/\/)', url):
++ yield from bot.coro_send_message(event.conv_id, "<i>Portal Info requested, please wait...</i>")
++ filepath = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name
++ portalinfoResponse = tempfile.NamedTemporaryFile(prefix="response_{}".format(event.conv_id), delete=False).name
++ filename = filepath.split('/', filepath.count('/'))[-1]
++ args_filepath = tempfile.NamedTemporaryFile(prefix="args_{}".format(event.conv_id), suffix=".json", delete=False).name
++
++ arguments['url'] = url
++ arguments['filepath'] = filepath
++ arguments['screenshotfunction'] = "portalinfoText"
++ arguments['portalinfoResponse'] = portalinfoResponse
++
++ with open(args_filepath, 'w') as out:
++ out.write(json.dumps(arguments))
++
++ try:
++ loop = asyncio.get_event_loop()
++ image_data = yield from _screencap(url, args_filepath, filepath, filename, bot, event, arguments)
++ except Exception as e:
++ yield from bot.coro_send_message(event.conv_id, "<i>error getting screenshot</i>")
++ logger.exception("screencap failed".format(url))
++ return
++ else:
++ html = "<i><b>{}</b> No URL found in Arguments".format(event.user.full_name)
++ yield from bot.coro_send_message(event.conv, html)
++
+ def intel(bot, event, *args):
+ """get a screenshot of a search term or intel URL or the default intel URL of the hangout."""
+
+@@ -195,13 +325,14 @@ def intel(bot, event, *args):
+ arguments['url'] = url
+ arguments['filepath'] = filepath
+ arguments['maptype'] = "intel"
++ arguments['screenshotfunction'] = "map"
+
+ with open(args_filepath, 'w') as out:
+ out.write(json.dumps(arguments))
+
+ try:
+ loop = asyncio.get_event_loop()
+- image_data = yield from _screencap(url, args_filepath, filepath, filename, bot, event)
++ image_data = yield from _screencap(url, args_filepath, filepath, filename, bot, event, arguments)
+ except Exception as e:
+ yield from bot.coro_send_message(event.conv_id, "<i>error getting screenshot</i>")
+ logger.exception("screencap failed".format(url))
+@@ -291,13 +422,14 @@ def iitc(bot, event, *args):
+ arguments['url'] = url
+ arguments['filepath'] = filepath
+ arguments['maptype'] = "iitc"
++ arguments['screenshotfunction'] = "map"
+
+ with open(args_filepath, 'w') as out:
+ out.write(json.dumps(arguments))
+
+ try:
+ loop = asyncio.get_event_loop()
+- image_data = yield from _screencap(url, args_filepath, filepath, filename, bot, event)
++ image_data = yield from _screencap(url, args_filepath, filepath, filename, bot, event, arguments)
+ except Exception as e:
+ yield from bot.coro_send_message(event.conv_id, "<i>error getting screenshot</i>")
+ logger.exception("screencap failed".format(url))
+diff --git a/screencap.js b/screencap.js
+index 0a6eb83..364e01f 100644
+--- a/screencap.js
++++ b/screencap.js
+@@ -22,6 +22,10 @@ if (args.length === 1) {
+ var filepath = arguments['filepath']
+ var user = arguments['email']
+ var pass = arguments['password']
++ var screenshotfunction = arguments['screenshotfunction']
++ if(screenshotfunction == "portalinfoText"){
++ var portalinfoResponse = arguments['portalinfoResponse']
++ }
+ }
+
+ function loadCookies(callback) {
+@@ -171,11 +175,220 @@ function login(l, p, url) {
+ });
+ }
+
++function map(search){
++ setTimeout(function() {
++ if (search != 'nix') {
++ searchfunc(search);
++ }
++ waitFor({
++ timeout: 240000,
++ check: function () {
++ return page.evaluate(function(zoomlevel) {
++ if (document.querySelector('.map').textContent.indexOf('done') != -1) {
++ return true;
++ }else{
++ console.log('generateFakeOutput')
++ return false;
++ }
++ }, zoomlevel);
++ },
++ 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");
++}
++
++function portalinfoScreen(){
++ setTimeout(function() {
++ 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 clipRect = page.evaluate(function(){
++ return document.querySelector('#sidebar').getBoundingClientRect();
++ });
++ page.evaluate(function(){
++ document.querySelector('#playerstat').style.display = 'none';
++ document.querySelector('#searchwrapper').style.display = 'none';
++ document.querySelector('#redeem').style.display = 'none';
++ });
++ setTimeout(function() {
++ var elementHeight = page.evaluate(function(){
++ return $("#sidebar").height();
++ });
++
++ page.clipRect = {
++ top: clipRect.top,
++ left: clipRect.left,
++ width: clipRect.width,
++ height: elementHeight
++ }
++ setTimeout(function() {s(filepath)}, "1000");
++ }, "2000");
++ },
++ error: function () {
++ var clipRect = page.evaluate(function(){
++ return document.querySelector('#sidebar').getBoundingClientRect();
++ });
++
++ setTimeout(function() {
++ var elementHeight = page.evaluate(function(){
++ return $("#sidebar").height();
++ });
++
++ page.clipRect = {
++ top: clipRect.top,
++ left: clipRect.left,
++ width: clipRect.width,
++ height: elementHeight
++ }
++ setTimeout(function() {s(filepath)}, "1000");
++ }, "2000");
++ }
++ });
++ }, "1000");
++}
++
++function portalinfoText(){
++ setTimeout(function() {
++ waitFor({
++ timeout: 240000,
++ check: function () {
++ return page.evaluate(function() {
++ if ((document.querySelector('.map').textContent.indexOf('done') != -1) || (document.getElementById("resodetails").rows[0])) {
++ return true;
++ }else{
++ console.log('generateFakeOutput')
++ return false;
++ }
++ });
++ },
++ success: function () {
++ var PortalName = page.evaluate(function(){
++ return document.getElementById("portaldetails").getElementsByClassName("title")[0].innerHTML;
++ });
++ var reso1 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[0].cells[1].firstElementChild.getAttribute("title");
++ });
++ var reso2 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[0].cells[2].firstElementChild.getAttribute("title");
++ });
++ var reso3 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[1].cells[1].firstElementChild.getAttribute("title");
++ });
++ var reso4 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[1].cells[2].firstElementChild.getAttribute("title");
++ });
++ var reso5 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[2].cells[1].firstElementChild.getAttribute("title");
++ });
++ var reso6 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[2].cells[2].firstElementChild.getAttribute("title");
++ });
++ var reso7 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[3].cells[1].firstElementChild.getAttribute("title");
++ });
++ var reso8 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[3].cells[2].firstElementChild.getAttribute("title");
++ });
++ var text = PortalName.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><br /><b>Resonator 1:</b><br />" + reso1.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 2:</b><br />" + reso2.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 3:</b><br />" + reso3.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 4:</b><br />" + reso4.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 5:</b><br />" + reso5.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 6:</b><br />" + reso6.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 7:</b><br />" + reso7.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 8:</b><br />" + reso8.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ')
++ console.log(text)
++ fs.write(portalinfoResponse, text, 'w');
++ 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);
++ },
++ error: function () {
++ var PortalName = page.evaluate(function(){
++ return document.getElementById("portaldetails").getElementsByClassName("title")[0].innerHTML;
++ });
++ var reso1 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[0].cells[1].firstElementChild.getAttribute("title");
++ });
++ var reso2 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[0].cells[2].firstElementChild.getAttribute("title");
++ });
++ var reso3 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[1].cells[1].firstElementChild.getAttribute("title");
++ });
++ var reso4 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[1].cells[2].firstElementChild.getAttribute("title");
++ });
++ var reso5 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[2].cells[1].firstElementChild.getAttribute("title");
++ });
++ var reso6 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[2].cells[2].firstElementChild.getAttribute("title");
++ });
++ var reso7 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[3].cells[1].firstElementChild.getAttribute("title");
++ });
++ var reso8 = page.evaluate(function(){
++ return document.getElementById("resodetails").rows[3].cells[2].firstElementChild.getAttribute("title");
++ });
++ var text = PortalName.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><br /><b>Resonator 1:</b><br />" + reso1.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 2:</b><br />" + reso2.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 3:</b><br />" + reso3.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 4:</b><br />" + reso4.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 5:</b><br />" + reso5.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 6:</b><br />" + reso6.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 7:</b><br />" + reso7.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ') + "<br /><b>Resonator 8:</b><br />" + reso8.replace(/(?:\r\n|\r|\n)/g, '<br />').replace(/(?:\t)/g, ' ')
++ console.log(text)
++ fs.write(portalinfoResponse, text.replace(/'/g, ''), 'w');
++ 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);
++ }
++ });
++ }, "1000");
++}
++
+ function afterLogin(url, search, mode) {
+ page.viewportSize = { width: '1280', height: '720' };
+ page.open(url, function(status) {
+ console.log(url)
+- if (status !== 'success') {console.log('unable to connect to remote server afterPlainLogin'); phantom.exit(0);}
++ if (status !== 'success') {console.log('unable to connect to remote server after Login'); phantom.exit(0);}
+ if (!isSignedIn()) {
+ if(mode =="cookie"){
+ if(fs.exists(cookiespath)) {
+@@ -190,50 +403,13 @@ function afterLogin(url, search, mode) {
+ storeCookies();
+ }
+ setupIITC()
+- setTimeout(function() {
+- if (search != 'nix') {
+- searchfunc(search);
+- }
+- waitFor({
+- timeout: 240000,
+- check: function () {
+- return page.evaluate(function(zoomlevel) {
+- if (document.querySelector('.map').textContent.indexOf('done') != -1) {
+- return true;
+- }else{
+- console.log('generateFakeOutput')
+- return false;
+- }
+- }, zoomlevel);
+- },
+- 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");
++ if(screenshotfunction == "map"){
++ map(search);
++ }else if (screenshotfunction == "portalinfoScreen"){
++ portalinfoScreen();
++ }else if (screenshotfunction == "portalinfoText"){
++ portalinfoText();
++ }
+ }, "1000");
+ });
+ }
diff --git a/pulls/7.json b/pulls/7.json
@@ -0,0 +1,22 @@
+{
+ "number": 7,
+ "title": "Add Portal info Commands",
+ "state": "merged",
+ "diff_file": "7.diff",
+ "author": "MTRNord",
+ "created_at": "2017-02-13T18:47:56Z",
+ "closed_at": "2017-03-06T19:00:52Z",
+ "merged_at": "2017-03-06T19:00:52Z",
+ "base_ref": "master",
+ "head_ref": "PortalInfo",
+ "labels": [
+ "enhancement"
+ ],
+ "assignees": [
+ "MTRNord"
+ ],
+ "requested_reviewers": [],
+ "body": "This Pull provides the commands\r\n\r\n/portalpic [url to portal]\r\n/portalinfo [url to portal]\r\n",
+ "comments": [],
+ "review_comments": []
+}
diff --git a/pulls/7.md b/pulls/7.md
@@ -0,0 +1,19 @@
+# PR #7 Add Portal info Commands
+
+- **Status:** merged
+- **Author:** @MTRNord
+- **Created:** 2017-02-13T18:47:56Z
+- **Branch:** PortalInfo → master
+- **Merged:** 2017-03-06T19:00:52Z
+- **Labels:** enhancement
+- **Assignees:** @MTRNord
+- **Diff:** [7.diff](./7.diff)
+
+---
+
+This Pull provides the commands
+
+/portalpic [url to portal]
+/portalinfo [url to portal]
+
+