intel-screenbot.meta

Issues/PRs archive for MTRNord/intel_screenbot
git clone git://archive.git.mtrnord.blog/MTRNord/intel-screenbot.meta.git
Log | Files | Refs

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:
Aissues/3.json | 16++++++++++++++++
Aissues/3.md | 13+++++++++++++
Aissues/6.json | 17+++++++++++++++++
Aissues/6.md | 12++++++++++++
Aissues/8.json | 21+++++++++++++++++++++
Aissues/8.md | 18++++++++++++++++++
Aissues/9.json | 15+++++++++++++++
Aissues/9.md | 11+++++++++++
Apulls/1.diff | 1129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apulls/1.json | 18++++++++++++++++++
Apulls/1.md | 19+++++++++++++++++++
Apulls/10.diff | 13+++++++++++++
Apulls/10.json | 18++++++++++++++++++
Apulls/10.md | 13+++++++++++++
Apulls/2.diff | 1023+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apulls/2.json | 22++++++++++++++++++++++
Apulls/2.md | 15+++++++++++++++
Apulls/4.diff | 1079+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apulls/4.json | 18++++++++++++++++++
Apulls/4.md | 17+++++++++++++++++
Apulls/5.diff | 792+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apulls/5.json | 18++++++++++++++++++
Apulls/5.md | 13+++++++++++++
Apulls/7.diff | 579+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apulls/7.json | 22++++++++++++++++++++++
Apulls/7.md | 19+++++++++++++++++++
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&ltmpl=' ++ page.open(link, function () { ++ login(SACSID, CSRF); ++ }); ++ }); ++} ++ ++function login(l, p) { ++ if (document.querySelector('#timeoutError')){ ++ login(l, p) ++ firePlainLogin(l, p) ++ } ++ waitFor({ ++ timeout: loginTimeout*2, ++ check: function () { ++ return page.evaluate(function() { ++ if (document.querySelector('#gaia_loginform')) { ++ return true; ++ }else{ ++ return false; ++ } ++ }); ++ }, ++ success: function () { ++ page.evaluate(function (l) { ++ document.getElementById('Email').value = l; ++ }, l); ++ page.evaluate(function () { ++ document.querySelector("#next").click(); ++ }); ++ window.setTimeout(function () { ++ page.evaluate(function (p) { ++ document.getElementById('Passwd').value = p; ++ }, p); ++ if(document.querySelector("#next")){ ++ page.evaluate(function () { ++ document.querySelector("#next").click(); ++ }); ++ }else{ ++ page.evaluate(function () { ++ document.querySelector("#signIn").click(); ++ }); ++ } ++ window.setTimeout(function () { ++ if (page.url.substring(0,40) === 'https://accounts.google.com/ServiceLogin') { ++ quit('login failed: wrong email and/or password'); ++ } ++ ++ if (page.url.substring(0,40) === 'https://appengine.google.com/_ah/loginfo') { ++ page.evaluate(function () { ++ document.getElementById('persist_checkbox').checked = true; ++ document.getElementsByTagName('form').submit(); ++ }); ++ } ++ ++ if (page.url.substring(0,44) === 'https://accounts.google.com/signin/challenge') { ++ twostep = system.stdin.readLine(); ++ } ++ window.setTimeout(afterPlainLogin(IntelURL, search), loginTimeout); ++ }, loginTimeout) ++ }, loginTimeout / 10); ++ }, ++ error: function () { ++ quit(); ++ } ++ }); ++} ++ ++function afterPlainLogin(IntelURL, search) { ++ page.viewportSize = { width: '1280', height: '720' }; ++ page.open(IntelURL, function(status) { ++ if (status !== 'success') {quit('unable to connect to remote server')} ++ if (!isSignedIn()) { ++ console.log("not logged in") ++ quit(); ++ } ++ setTimeout(function() { ++ setupIITC() ++ setTimeout(function() { ++ setTimeout(function() {if (search != "nix") {searchfunc(search);}}, 1000); ++ waitFor({ ++ timeout: 240000, ++ check: function () { ++ return page.evaluate(function() { ++ if (document.querySelector('.map').textContent.indexOf('done') != -1) { ++ return true; ++ }else{ ++ console.log('generateFakeOutput') ++ return false; ++ } ++ }); ++ }, ++ success: function () { ++ var startTime = new Date().getTime(); ++ var interval = setInterval(function(){ ++ if(new Date().getTime() - startTime > 5000){ ++ hideDebris(); ++ prepare('1280', '720'); ++ main(); ++ clearInterval(interval); ++ return; ++ } ++ console.log('generateFakeOutput') ++ }, 1000); ++ }, ++ error: function () { ++ var startTime = new Date().getTime(); ++ var interval = setInterval(function(){ ++ if(new Date().getTime() - startTime > 5000){ ++ hideDebris(); ++ prepare('1280', '720'); ++ main(); ++ clearInterval(interval); ++ return; ++ } ++ console.log('generateFakeOutput') ++ }, 1000); ++ } ++ }); ++ }, "1000"); ++ }, "1000"); ++ }); ++} ++ ++ ++ + function addCookies(sacsid, csrf) { + phantom.addCookie({ + name: 'SACSID', +@@ -46,11 +239,9 @@ function waitFor ($config) { + $config._start = $config._start || new Date(); + if ($config.timeout && new Date - $config._start > $config.timeout) { + if ($config.error) $config.error(); +- if ($config.debug) console.log('timedout ' + (new Date - $config._start) + 'ms'); + return; + } + if ($config.check()) { +- if ($config.debug) console.log('success ' + (new Date - $config._start) + 'ms'); + return $config.success(); + } + setTimeout(waitFor, $config.interval || 0, $config); +@@ -69,95 +260,141 @@ function loadLocalIitcPlugin(src) { + page.injectJs(src) + } + +-addCookies(SACSID, CSRF); +-afterCookieLogin(IntelURL, search); +- + function afterCookieLogin(IntelURL, search) { +- page.viewportSize = { width: '1920', height: '1080' }; ++ page.viewportSize = { width: '1280', height: '720' }; + page.open(IntelURL, function(status) { + if (status !== 'success') {quit('unable to connect to remote server')} +- page.injectJs('https://code.jquery.com/jquery-3.1.1.min.js'); ++ if(!isSignedIn()) { ++ if(fs.exists(cookiespath)) { ++ fs.remove(cookiespath); ++ } ++ if(validateEmail(SACSID)) { ++ page.deleteCookie('SACSID'); ++ page.deleteCookie('csrftoken'); ++ firePlainLogin(SACSID, CSRF); ++ return; ++ } else { ++ quit('Cookies are obsolete. Update your config file.'); ++ } ++ } + setTimeout(function() { +- page.evaluate(function() { +- localStorage['ingress.intelmap.layergroupdisplayed'] = JSON.stringify({ +- "Unclaimed Portals":Boolean(1 === 1), +- "Level 1 Portals":Boolean(1 === 1), +- "Level 2 Portals":Boolean((1 <= 2) && (8 >= 2)), +- "Level 3 Portals":Boolean((1 <= 3) && (8 >= 3)), +- "Level 4 Portals":Boolean((1 <= 4) && (8 >= 4)), +- "Level 5 Portals":Boolean((1 <= 5) && (8 >= 5)), +- "Level 6 Portals":Boolean((1 <= 6) && (8 >= 6)), +- "Level 7 Portals":Boolean((1 <= 7) && (8 >= 7)), +- "Level 8 Portals":Boolean(8 === 8), +- "DEBUG Data Tiles":false, +- "Artifacts":true, +- "Ornaments":true +- }); +- var script = document.createElement('script'); +- script.type='text/javascript'; +- script.src='https://secure.jonatkins.com/iitc/release/total-conversion-build.user.js'; +- document.head.insertBefore(script, document.head.lastChild); +- }); +- loadIitcPlugin('http://iitc.jonatkins.com/release/plugins/canvas-render.user.js'); +- var plugins = JSON.parse(fs.read(plugins_file)); +- for(var i in plugins){ +- var plugin = plugins[i]; +- if(plugin.match('^[a-zA-Z]+://')){ +- loadIitcPlugin(plugin); +- }else{ +- loadLocalIitcPlugin(plugin); +- } +- } ++ setupIITC() + setTimeout(function() { +- if (search != "nix") { +- page.evaluate(function(search) { +- if (document.querySelector('#search')){ +- window.setTimeout(function() { +- document.getElementById("search").value=search; +- var e = jQuery.Event("keypress"); +- e.which = 13; +- e.keyCode = 13; +- $("#search").trigger(e); +- }, 2000); +- var checkExist = setInterval(function() { +- if ($('.searchquery').length > 0) { +- window.setTimeout(function() {$('.searchquery > :nth-child(2)').children()[0].click();}, 1000); +- clearInterval(checkExist); +- } +- }, 100); +- } +- }, search); +- } ++ if (search != "nix") {searchfunc(search);} + waitFor({ +- timeout: 120000, ++ timeout: 240000, + check: function () { + return page.evaluate(function() { + if (document.querySelector('.map').textContent.indexOf('done') != -1) { + return true; + }else{ ++ console.log('generateFakeOutput') + return false; + } + }); + }, + success: function () { +- hideDebris(); +- prepare('1920', '1080'); +- main(); ++ var startTime = new Date().getTime(); ++ var interval = setInterval(function(){ ++ if(new Date().getTime() - startTime > 5000){ ++ hideDebris(); ++ prepare('1280', '720'); ++ main(); ++ clearInterval(interval); ++ return; ++ } ++ console.log('generateFakeOutput') ++ }, 1000); + }, + error: function () { +- hideDebris(); +- prepare('1920', '1080'); +- main(); ++ var startTime = new Date().getTime(); ++ var interval = setInterval(function(){ ++ if(new Date().getTime() - startTime > 5000){ ++ hideDebris(); ++ prepare('1280', '720'); ++ main(); ++ clearInterval(interval); ++ return; ++ } ++ console.log('generateFakeOutput') ++ }, 1000); + } + }); +- }, "5000"); +- }, "5000"); ++ }, "1000"); ++ }, "1000"); + }); + } + ++function searchfunc(search){ ++ page.evaluate(function(search) { ++ if (document.querySelector('#search')){ ++ window.addHook('search', function(query) { ++ var checkExist = setInterval(function() { ++ if (query.results.length > 0) { ++ console.warn(query.results) ++ map.fitBounds(query.results[0].bounds, {maxZoom: 17}) ++ clearInterval(checkExist); ++ } ++ }, 100); ++ }); ++ setTimeout(function() { ++ window.search.doSearch(search, true) ++ }, 2000); ++ } ++ }, search); ++} ++ ++function setupIITC(){ ++ loadIitcPlugin('https://static.iitc.me/build/release/plugins/canvas-render.user.js'); ++ page.evaluate(function() { ++ localStorage['ingress.intelmap.layergroupdisplayed'] = JSON.stringify({ ++ "Unclaimed Portals": true, ++ "Level 1 Portals": true, ++ "Level 2 Portals": true, ++ "Level 3 Portals": true, ++ "Level 4 Portals": true, ++ "Level 5 Portals": true, ++ "Level 6 Portals": true, ++ "Level 7 Portals": true, ++ "Level 8 Portals": true, ++ "Fields": true, ++ "Links": true, ++ "Resistance": true, ++ "Enlightened": true, ++ "DEBUG Data Tiles":false, ++ "Artifacts":true, ++ "Ornaments":true ++ }); ++ var script = document.createElement('script'); ++ script.type='text/javascript'; ++ script.src='https://static.iitc.me/build/test/total-conversion-build.user.js'; ++ document.head.insertBefore(script, document.head.lastChild); ++ localStorage['iitc-base-map'] = 'Google Roads'; ++ }); ++ var plugins = JSON.parse(fs.read(plugins_file)); ++ for(var i in plugins){ ++ var plugin = plugins[i]; ++ if(plugin.match('^[a-zA-Z]+://')){ ++ loadIitcPlugin(plugin); ++ }else{ ++ loadLocalIitcPlugin(plugin); ++ } ++ } ++} ++ + function s(file) { ++ console.log('SCREENSHOT') + page.render(file); +- phantom.exit(0); ++ var startTime = new Date().getTime(); ++ var startTime = new Date().getTime(); ++ var interval = setInterval(function(){ ++ if(new Date().getTime() - startTime > 5000){ ++ clearInterval(interval); ++ phantom.exit(0); ++ return; ++ } ++ console.log('doSomeOutput') ++ }, 1000); + } + + function hideDebris() { +@@ -170,14 +407,14 @@ function hideDebris() { + if (document.querySelector('#sidebartoggle')) {document.querySelector('#sidebartoggle').style.display = 'none';} + if (document.querySelector('#scrollwrapper')) {document.querySelector('#scrollwrapper').style.display = 'none';} + if (document.querySelector('.leaflet-control-container')) {document.querySelector('.leaflet-control-container').style.display = 'none';} ++ if (document.querySelector('#portal_highlight_select')) {document.querySelector('#portal_highlight_select').style.display = 'none';} + }); +- }, 2000); ++ }, 200); + } + + function prepare(widthz, heightz) { +- window.setTimeout(function() { +- page.evaluate(function(w, h) { +- $("span:contains(' Google Roads')").prev().click(); ++ window.setTimeout(function() { ++ page.evaluate(function(w, h) { + var water = document.createElement('p'); + water.id='viewport-ice'; + water.style.position = 'absolute'; +@@ -188,10 +425,10 @@ function prepare(widthz, heightz) { + water.style.width = w + 'px'; + water.style.height = h + 'px'; + document.querySelectorAll('body')[0].appendChild(water); +- }, widthz, heightz); +- var selector = "#viewport-ice"; +- setElementBounds(selector); +- }, 4000); ++ }, widthz, heightz); ++ var selector = "#viewport-ice"; ++ setElementBounds(selector); ++ }, 500); + } + + +@@ -241,10 +478,10 @@ function getDateTime(format) { + } + + function addTimestamp(time) { +- page.evaluate(function(dateTime) { ++ page.evaluate(function(dateTime, search) { + var water = document.createElement('p'); + water.id='watermark-ice'; +- water.innerHTML = dateTime; ++ water.innerHTML = dateTime + ' - ' + search; + water.style.position = 'absolute'; + water.style.color = '#3A539B'; + water.style.top = '0'; +@@ -255,9 +492,9 @@ function addTimestamp(time) { + water.style.fontSize = '40px'; + water.style.opacity = '0.8'; + water.style.fontFamily = 'monospace'; +- water.style.textShadow = 'rgb(3, 3, 3) 7px 5px 9px'; ++ water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)'; + document.querySelectorAll('body')[0].appendChild(water); +- }, time); ++ }, time, search); + } + + /** +@@ -274,5 +511,5 @@ function main() { + addTimestamp(getDateTime(0)); + file = filepath; + s(file); +- }, 3000); ++ }, 400); + } +diff --git a/screencap_intel.js b/screencap_intel.js +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&ltmpl=' ++ ++ page.open(link, function () { ++ login(SACSID, CSRF); ++ }); ++ }); ++} ++ ++function loadCookies(callback) { ++ if(fs.exists(cookiespath)) { ++ var stream = fs.open(cookiespath, 'r'); ++ ++ while(!stream.atEnd()) { ++ var line = stream.readLine().split('='); ++ if(line[0] === 'SACSID') { ++ config.SACSID = line[1]; ++ } else if(line[0] === 'csrftoken') { ++ config.CSRF = line[1]; ++ } else { ++ config.SACSID = ''; ++ config.CSRF = ''; ++ } ++ } ++ stream.close(); ++ } ++ callback(); ++} ++ ++function isSignedIn() { ++ return page.evaluate(function() { ++ return document.getElementsByTagName('a')[0].innerText.trim() !== 'Sign in'; ++ }); ++} ++ ++function storeCookies() { ++ var cookies = page.cookies; ++ fs.write(cookiespath, '', 'w'); ++ for(var i in cookies) { ++ fs.write(cookiespath, cookies[i].name + '=' + cookies[i].value +'\n', 'a'); ++ } ++} ++ ++function login(l, p) { ++ if (document.querySelector('#timeoutError')){ ++ login(l, p) ++ firePlainLogin(l, p) ++ } ++ waitFor({ ++ timeout: 240000, ++ check: function () { ++ return page.evaluate(function() { ++ if (document.querySelector('#gaia_loginform')) { ++ return true; ++ }else{ ++ return false; ++ } ++ }); ++ }, ++ success: function () { ++ page.evaluate(function (l) { ++ document.getElementById('Email').value = l; ++ }, l); ++ page.evaluate(function () { ++ document.querySelector("#next").click(); ++ }); ++ window.setTimeout(function () { ++ page.evaluate(function (p) { ++ document.getElementById('Passwd').value = p; ++ }, p); ++ if(document.querySelector("#next")){ ++ page.evaluate(function () { ++ document.querySelector("#next").click(); ++ }); ++ }else{ ++ page.evaluate(function () { ++ document.querySelector("#signIn").click(); ++ }); ++ } ++// page.evaluate(function () { ++// document.getElementById('gaia_loginform').submit(); ++// }); ++ window.setTimeout(function () { ++ if (page.url.substring(0,40) === 'https://accounts.google.com/ServiceLogin') { ++ quit('login failed: wrong email and/or password'); ++ } ++ ++ if (page.url.substring(0,40) === 'https://appengine.google.com/_ah/loginfo') { ++ page.evaluate(function () { ++ document.getElementById('persist_checkbox').checked = true; ++ document.getElementsByTagName('form').submit(); ++ }); ++ } ++ ++ if (page.url.substring(0,44) === 'https://accounts.google.com/signin/challenge') { ++ twostep = system.stdin.readLine(); ++ } ++ ++ // if (twostep) { ++ // page.evaluate(function (code) { ++ // document.getElementById('totpPin').value = code; ++ // }, twostep); ++ // page.evaluate(function () { ++ // document.getElementById('submit').click(); ++ // document.getElementById('challenge').submit(); ++ // }); ++ // } ++ window.setTimeout(afterPlainLogin(IntelURL, search), loginTimeout); ++ }, loginTimeout) ++ }, loginTimeout / 10); ++ }, ++ error: function () { ++ quit(); ++ } ++ }); ++} ++ ++function afterPlainLogin(IntelURL, search) { ++ page.open(IntelURL, function(status) { ++ if (status !== 'success') {quit('unable to connect to remote server')} ++ ++ if (!isSignedIn()) { ++ console.log('Something went wrong. Please, sign in to Google via your browser and restart ICE. Don\'t worry, your Ingress account will not be affected.'); ++ quit(); ++ } ++ setTimeout(function() { ++ storeCookies(); ++ waitFor({ ++ timeout: 240000, ++ check: function () { ++ return page.evaluate(function() { ++ if (document.querySelector('#percent_text').textContent.indexOf('90') != -1) { ++ if (!document.getElementById("loading_msg").style.display){ ++ return true; ++ }else{ ++ return false; ++ } ++ }else{ ++ return false; ++ } ++ }); ++ }, ++ success: function () { ++ page.evaluate(function() { ++ document.querySelector("#filters_container").style.display= 'none'; ++ }); ++ hideDebris(); ++ prepare('1920', '1080', search); ++ main(); ++ }, ++ error: function () { ++ page.evaluate(function() { ++ document.querySelector("#filters_container").style.display= 'none'; ++ }); ++ hideDebris(); ++ prepare('1920', '1080', search); ++ main(); ++ } ++ }); ++ }, "5000"); ++ }); ++} + + function addCookies(sacsid, csrf) { + phantom.addCookie({ +@@ -59,10 +253,22 @@ function waitFor ($config) { + function afterCookieLogin(IntelURL, search) { + page.open(IntelURL, function(status) { + if (status !== 'success') {quit('unable to connect to remote server')} +- ++ if(!isSignedIn()) { ++ if(fs.exists(cookiespath)) { ++ fs.remove(cookiespath); ++ } ++ if(validateEmail(SACSID)) { ++ page.deleteCookie('SACSID'); ++ page.deleteCookie('csrftoken'); ++ firePlainLogin(SACSID, CSRF); ++ return; ++ } else { ++ quit('Cookies are obsolete. Update your config file.'); ++ } ++ } + setTimeout(function() { + waitFor({ +- timeout: 120000, ++ timeout: 240000, + check: function () { + return page.evaluate(function() { + if (document.querySelector('#percent_text').textContent.indexOf('90') != -1) { 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&ltmpl=' + 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&ltmpl=' +- +- page.open(link, function () { +- login(SACSID, CSRF); +- }); +- }); +-} +- +-function loadCookies(callback) { +- if(fs.exists(cookiespath)) { +- var stream = fs.open(cookiespath, 'r'); +- +- while(!stream.atEnd()) { +- var line = stream.readLine().split('='); +- if(line[0] === 'SACSID') { +- config.SACSID = line[1]; +- } else if(line[0] === 'csrftoken') { +- config.CSRF = line[1]; +- } else { +- config.SACSID = ''; +- config.CSRF = ''; +- } +- } +- stream.close(); +- } +- callback(); +-} +- +-function isSignedIn() { +- return page.evaluate(function() { +- return document.getElementsByTagName('a')[0].innerText.trim() !== 'Sign in'; +- }); +-} +- +-function storeCookies() { +- var cookies = page.cookies; +- fs.write(cookiespath, '', 'w'); +- for(var i in cookies) { +- fs.write(cookiespath, cookies[i].name + '=' + cookies[i].value +'\n', 'a'); +- } +-} +- +-function login(l, p) { +- if (document.querySelector('#timeoutError')){ +- login(l, p) +- firePlainLogin(l, p) +- } +- waitFor({ +- timeout: 240000, +- check: function () { +- return page.evaluate(function() { +- if (document.querySelector('#gaia_loginform')) { +- return true; +- }else{ +- return false; +- } +- }); +- }, +- success: function () { +- page.evaluate(function (l) { +- document.getElementById('Email').value = l; +- }, l); +- page.evaluate(function () { +- document.querySelector("#next").click(); +- }); +- window.setTimeout(function () { +- page.evaluate(function (p) { +- document.getElementById('Passwd').value = p; +- }, p); +- if(document.querySelector("#next")){ +- page.evaluate(function () { +- document.querySelector("#next").click(); +- }); +- }else{ +- page.evaluate(function () { +- document.querySelector("#signIn").click(); +- }); +- } +-// page.evaluate(function () { +-// document.getElementById('gaia_loginform').submit(); +-// }); +- window.setTimeout(function () { +- if (page.url.substring(0,40) === 'https://accounts.google.com/ServiceLogin') { +- quit('login failed: wrong email and/or password'); +- } +- +- if (page.url.substring(0,40) === 'https://appengine.google.com/_ah/loginfo') { +- page.evaluate(function () { +- document.getElementById('persist_checkbox').checked = true; +- document.getElementsByTagName('form').submit(); +- }); +- } +- +- if (page.url.substring(0,44) === 'https://accounts.google.com/signin/challenge') { +- twostep = system.stdin.readLine(); +- } +- +- // if (twostep) { +- // page.evaluate(function (code) { +- // document.getElementById('totpPin').value = code; +- // }, twostep); +- // page.evaluate(function () { +- // document.getElementById('submit').click(); +- // document.getElementById('challenge').submit(); +- // }); +- // } +- window.setTimeout(afterPlainLogin(IntelURL, search), loginTimeout); +- }, loginTimeout) +- }, loginTimeout / 10); +- }, +- error: function () { +- quit(); +- } +- }); +-} +- +-function afterPlainLogin(IntelURL, search) { +- page.open(IntelURL, function(status) { +- if (status !== 'success') {quit('unable to connect to remote server')} +- +- if (!isSignedIn()) { +- console.log('Something went wrong. Please, sign in to Google via your browser and restart ICE. Don\'t worry, your Ingress account will not be affected.'); +- quit(); +- } +- setTimeout(function() { +- storeCookies(); +- waitFor({ +- timeout: 240000, +- check: function () { +- return page.evaluate(function() { +- if (document.querySelector('#percent_text').textContent.indexOf('90') != -1) { +- if (!document.getElementById("loading_msg").style.display){ +- return true; +- }else{ +- return false; +- } +- }else{ +- return false; +- } +- }); +- }, +- success: function () { +- page.evaluate(function() { +- document.querySelector("#filters_container").style.display= 'none'; +- }); +- hideDebris(); +- prepare('1920', '1080', search); +- main(); +- }, +- error: function () { +- page.evaluate(function() { +- document.querySelector("#filters_container").style.display= 'none'; +- }); +- hideDebris(); +- prepare('1920', '1080', search); +- main(); +- } +- }); +- }, "5000"); +- }); +-} +- +-function addCookies(sacsid, csrf) { +- phantom.addCookie({ +- 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&ltmpl=' + 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] + +