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

2.diff (40213B)


      1 diff --git a/README.md b/README.md
      2 index 5dcbdb8..d6a6132 100644
      3 --- a/README.md
      4 +++ b/README.md
      5 @@ -6,7 +6,7 @@ Requires: **PhantomJS** (installation instructions below)
      6  
      7  Requires: **[hangoutsbot](https://github.com/hangoutsbot/hangoutsbot)**
      8  
      9 -Get and post a screenshot of the Intel Map. 
     10 +Get and post a screenshot of the Intel Map.
     11  
     12  ## Install
     13  To install the plugin you need to:
     14 @@ -17,7 +17,9 @@ To install the plugin you need to:
     15  4. Run `pip3 install -r requirements.txt`
     16  5. Follow Configuration.
     17  
     18 -## Configuration
     19 +## Configuration with Cookies
     20 +
     21 +*Note Cookies do have to be changed on daily base*
     22  For using the Intel Screenbot you need to add the following to the config.json:
     23  
     24  ```
     25 @@ -25,7 +27,29 @@ For using the Intel Screenbot you need to add the following to the config.json:
     26     "SACSID": "YOUR SACSID",
     27     "CSRF": "YOUR CSRF",
     28     "plugin_dirs": [
     29 -     "http://iitc.jonatkins.com/release/plugins"
     30 +     "https://api.github.com/repos/iitc-project/iitc-project.github.io/git/trees/master?recursive=1"
     31 +   ]
     32 + }
     33 +```  
     34 +
     35 +According to the official INSTALL Documention of the hangoutbot you will find the config.json in `/<username>/.local/share/hangupsbot/`
     36 +(NOTE! add an comma behind the last element of the config.json and add it befor the outer element closes)
     37 +
     38 +Also you need to add `intel_screenbot` to the plugins.
     39 +
     40 +## Configuration with Email Password
     41 +
     42 +**IMPORTANT: DO NOT USE YOUR MAIN ACCOUNT! I AM NOT RESPONSIBLE IF YOU ACCOUNT GETS BANNED! USE AT YOUR OWN RISK**
     43 +
     44 +*Note DON'T set cookies up when using emil/password*
     45 +For using the Intel Screenbot you need to add the following to the config.json:
     46 +
     47 +```
     48 + "intel_screenbot": {
     49 +   "email": "YOUR EMAIL",
     50 +   "password": "YOUR Password",
     51 +   "plugin_dirs": [
     52 +     "https://api.github.com/repos/iitc-project/iitc-project.github.io/git/trees/master?recursive=1"
     53     ]
     54   }
     55  ```  
     56 @@ -85,7 +109,7 @@ You should look at the Documentation of [ingress-ice](https://github.com/nibogd/
     57  * Provide an arbitrary `<url>` to take a screenshot
     58  * If no `<url>` is supplied, use the default screenshot URL (or reply with an error if no URL is set)
     59  
     60 -## PhantomJS Installation 
     61 +## PhantomJS Installation
     62  
     63  *May be outdated*
     64  
     65 @@ -95,7 +119,7 @@ You should look at the Documentation of [ingress-ice](https://github.com/nibogd/
     66  
     67  ## Building PhantomJS from Source (Advanced)
     68  
     69 -Note: It is not within the scope of this project to discuss and resolve build problems with 
     70 +Note: It is not within the scope of this project to discuss and resolve build problems with
     71    external libraries.
     72  
     73  **Install dependencies**  
     74 diff --git a/TODO.md b/TODO.md
     75 index e89abdc..49ecbcf 100644
     76 --- a/TODO.md
     77 +++ b/TODO.md
     78 @@ -1,5 +1,9 @@
     79  # TODO
     80  
     81 -- Add `/bot iitc`
     82 +- Remove `/bot clear_iitcplugins`
     83 +- Add `/bot active_iitcplugins`
     84 +- Add zooming
     85 +- Add layer chooser
     86 +- Migrate intel command to iitc with default intel background layer
     87  - Add `/bot AP`
     88  - Add `/bot recharge`
     89 diff --git a/__init__.py b/__init__.py
     90 index 2648a61..39a0e12 100644
     91 --- a/__init__.py
     92 +++ b/__init__.py
     93 @@ -41,7 +41,7 @@ def _parse_onlineRepos(url, ext=''):
     94                  for tree in value:
     95                      for attribute, value in tree.items():
     96                          if attribute == "path":
     97 -                            if value.endswith(ext):
     98 +                            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:
     99                                  files.append(url.replace("https://api.github.com/repos/", "https://raw.githubusercontent.com/").replace("git/trees/",'').replace("master?recursive=1","master/") + value)
    100          return files
    101      else:
    102 @@ -78,11 +78,10 @@ def _get_iitc_plugins(bot):
    103      else:
    104          bot.memory.set_by_path(["iitc_plugins"], iitc_plugins)
    105  
    106 -@asyncio.coroutine
    107  def _get_lines(shell_command):
    108 -    p = yield from asyncio.create_subprocess_shell(shell_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    109 -    stdout, stderr = yield from p.communicate()
    110 -    return p.returncode, stdout
    111 +    p = yield from asyncio.create_subprocess_shell(shell_command)
    112 +    output = yield from p.wait()
    113 +    return p.returncode, output, True
    114  
    115  @asyncio.coroutine
    116  def _screencap(maptype, url, filepath, filename, SACSID, CSRF, plugins, search, bot, event):
    117 @@ -92,35 +91,38 @@ def _screencap(maptype, url, filepath, filename, SACSID, CSRF, plugins, search,
    118          if search == False:
    119              command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap_' + maptype + '.js "' + SACSID + '" "' + CSRF + '" "' + url + '" "' + filepath + '"'
    120              task = _get_lines(command)
    121 -            task = asyncio.wait_for(task, 180.0, loop=self.loop)
    122 -            exitcode, stdout = loop.run_until_complete(task)
    123 +            task = asyncio.wait_for(task, 420.0)
    124 +            exitcode, output, status = yield from task
    125          else:
    126              command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap_' + maptype + '.js "' + SACSID + '" "' + CSRF + '" "' + url + '" "' + filepath + '" "' + search + '"'
    127              task = _get_lines(command)
    128 -            task = asyncio.wait_for(task, 180.0, loop=loop)
    129 -            exitcode, stdout = yield from task
    130 +            task = asyncio.wait_for(task, 420.0)
    131 +            exitcode, output, status = yield from task
    132      else:
    133          if search == False:
    134              command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap_' + maptype + '.js "' + SACSID + '" "' + CSRF + '" "' + url + '" "' + filepath + '" "' + plugins + '"'
    135              task = _get_lines(command)
    136 -            task = asyncio.wait_for(task, 180.0, loop=self.loop)
    137 -            exitcode, stdout = loop.run_until_complete(task)
    138 +            task = asyncio.wait_for(task, 420.0)
    139 +            exitcode, output, status = yield from task
    140          else:
    141              command = 'phantomjs hangupsbot/plugins/intel_screenbot/screencap_' + maptype + '.js "' + SACSID + '" "' + CSRF + '" "' + url + '" "' + filepath + '" "' + search + '" "' + plugins + '"'
    142              task = _get_lines(command)
    143 -            task = asyncio.wait_for(task, 180.0, loop=loop)
    144 -            exitcode, stdout = yield from task
    145 +            task = asyncio.wait_for(task, 420.0)
    146 +            exitcode, output, status = yield from task
    147  
    148      # read the resulting file into a byte array
    149 +    # yield from asyncio.sleep(10)
    150      file_resource = yield from _open_file(filepath)
    151      file_data = yield from loop.run_in_executor(None, file_resource.read)
    152      image_data = yield from loop.run_in_executor(None, io.BytesIO, file_data)
    153 -    try:
    154 -        image_id = yield from bot._client.upload_image(image_data, filename=filename)
    155 -        yield from bot._client.sendchatmessage(event.conv.id_, None, image_id=image_id)
    156 -    except Exception as e:
    157 -        yield from bot.coro_send_message(event.conv_id, "<i>error uploading screenshot</i>")
    158 -        logger.exception("upload failed".format(url))
    159 +    if status:
    160 +        try:
    161 +            image_id = yield from bot._client.upload_image(image_data, filename=filename)
    162 +            yield from bot._client.sendchatmessage(event.conv.id_, None, image_id=image_id)
    163 +        except Exception as e:
    164 +            logger.exception("upload failed: {}".format(url))
    165 +            logger.exception("exception: {}".format(e))
    166 +            yield from bot.coro_send_message(event.conv_id, "<i>error uploading screenshot</i>")
    167  
    168  
    169  def setintel(bot, event, *args):
    170 @@ -168,14 +170,21 @@ def intel(bot, event, *args):
    171          url = bot.conversation_memory_get(event.conv_id, 'IntelURL')
    172  
    173      if bot.config.exists(["intel_screenbot", "SACSID"]):
    174 -        SACSID = bot.config.get_by_path(["intel_screenbot", "SACSID"])
    175 -    else:
    176 -        html = "<i><b>{}</b> No Intel SACSID Cookie has been added to config. Unable to authenticate".format(event.user.full_name)
    177 -        yield from bot.coro_send_message(event.conv, html)
    178 -    if bot.config.exists(["intel_screenbot", "CSRF"]):
    179 -        CSRF = bot.config.get_by_path(["intel_screenbot", "CSRF"])
    180 +        if bot.config.exists(["intel_screenbot", "CSRF"]):
    181 +            SACSID = bot.config.get_by_path(["intel_screenbot", "SACSID"])
    182 +            CSRF = bot.config.get_by_path(["intel_screenbot", "CSRF"])
    183 +        else:
    184 +            html = "<i><b>{}</b> No Intel password has been added to config. Unable to authenticate".format(event.user.full_name)
    185 +            yield from bot.coro_send_message(event.conv, html)
    186 +    elif bot.config.exists(["intel_screenbot", "email"]):
    187 +        if bot.config.exists(["intel_screenbot", "password"]):
    188 +            SACSID = bot.config.get_by_path(["intel_screenbot", "email"])
    189 +            CSRF = bot.config.get_by_path(["intel_screenbot", "password"])
    190 +        else:
    191 +            html = "<i><b>{}</b> No Intel password has been added to config. Unable to authenticate".format(event.user.full_name)
    192 +            yield from bot.coro_send_message(event.conv, html)
    193      else:
    194 -        html = "<i><b>{}</b> No Intel CSRF Cookie has been added to config. Unable to authenticate".format(event.user.full_name)
    195 +        html = "<i><b>{}</b> No Intel SACSID Cookie or Email/password has been added to config. Unable to authenticate".format(event.user.full_name)
    196          yield from bot.coro_send_message(event.conv, html)
    197  
    198      if url is None:
    199 @@ -200,8 +209,8 @@ def intel(bot, event, *args):
    200              url = 'https://www.ingress.com/intel'
    201              yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting as requested, please wait...</i>")
    202  
    203 -        filename = event.conv_id + "." + str(time.time()) +".png"
    204 -        filepath = tempfile.NamedTemporaryFile(prefix=event.conv_id, suffix=".png", delete=False).name
    205 +        filepath = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name
    206 +        filename = filepath.split('/', filepath.count('/'))[-1]
    207          logger.debug("temporary screenshot file: {}".format(filepath))
    208          try:
    209              loop = asyncio.get_event_loop()
    210 @@ -227,16 +236,23 @@ def iitc(bot, event, *args):
    211          url = bot.conversation_memory_get(event.conv_id, 'IntelURL')
    212  
    213      if bot.config.exists(["intel_screenbot", "SACSID"]):
    214 -        SACSID = bot.config.get_by_path(["intel_screenbot", "SACSID"])
    215 -    else:
    216 -        html = "<i><b>{}</b> No Intel SACSID Cookie has been added to config. Unable to authenticate".format(event.user.full_name)
    217 -        yield from bot.coro_send_message(event.conv, html)
    218 -    if bot.config.exists(["intel_screenbot", "CSRF"]):
    219 -        CSRF = bot.config.get_by_path(["intel_screenbot", "CSRF"])
    220 +        if bot.config.exists(["intel_screenbot", "CSRF"]):
    221 +            SACSID = bot.config.get_by_path(["intel_screenbot", "SACSID"])
    222 +            CSRF = bot.config.get_by_path(["intel_screenbot", "CSRF"])
    223 +        else:
    224 +            html = "<i><b>{}</b> No Intel password has been added to config. Unable to authenticate".format(event.user.full_name)
    225 +            yield from bot.coro_send_message(event.conv, html)
    226 +    elif bot.config.exists(["intel_screenbot", "email"]):
    227 +        if bot.config.exists(["intel_screenbot", "password"]):
    228 +            SACSID = bot.config.get_by_path(["intel_screenbot", "email"])
    229 +            CSRF = bot.config.get_by_path(["intel_screenbot", "password"])
    230 +        else:
    231 +            html = "<i><b>{}</b> No Intel password has been added to config. Unable to authenticate".format(event.user.full_name)
    232 +            yield from bot.coro_send_message(event.conv, html)
    233      else:
    234 -        html = "<i><b>{}</b> No Intel CSRF Cookie has been added to config. Unable to authenticate".format(event.user.full_name)
    235 +        html = "<i><b>{}</b> No Intel SACSID Cookie or Email/password has been added to config. Unable to authenticate".format(event.user.full_name)
    236          yield from bot.coro_send_message(event.conv, html)
    237 -
    238 +        
    239      if url is None:
    240          html = "<i><b>{}</b> No Intel URL has been set for screenshots.".format(event.user.full_name)
    241          yield from bot.coro_send_message(event.conv, html)
    242 @@ -259,8 +275,8 @@ def iitc(bot, event, *args):
    243              url = 'https://www.ingress.com/intel'
    244              yield from bot.coro_send_message(event.conv_id, "<i>intel map is searching " + search + " and screenshooting as requested, please wait...</i>")
    245  
    246 -        filename = event.conv_id + "." + str(time.time()) +".png"
    247 -        filepath = tempfile.NamedTemporaryFile(prefix=event.conv_id, suffix=".png", delete=False).name
    248 +        filepath = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name
    249 +        filename = filepath.split('/', filepath.count('/'))[-1]
    250          plugins_filepath = tempfile.NamedTemporaryFile(prefix=event.conv_id, suffix=".json", delete=False).name
    251          logger.debug("temporary screenshot file: {}".format(filepath))
    252          if bot.conversation_memory_get(event.conv_id, 'iitc_plugins'):
    253 @@ -273,10 +289,10 @@ def iitc(bot, event, *args):
    254                              plugins.append(plugin_objects["url"])
    255          else:
    256               plugins = ''
    257 -        
    258 +
    259          with open(plugins_filepath, 'w') as out:
    260              out.write(json.dumps(plugins))
    261 -        
    262 +
    263          try:
    264              loop = asyncio.get_event_loop()
    265              image_data = yield from _screencap("iitc", url, filepath, filename, SACSID, CSRF, plugins_filepath, search, bot, event)
    266 diff --git a/screencap_iitc.js b/screencap_iitc.js
    267 index c9413db..6fa062a 100644
    268 --- a/screencap_iitc.js
    269 +++ b/screencap_iitc.js
    270 @@ -2,6 +2,8 @@ var system = require('system');
    271  var args = system.args;
    272  var page = require('webpage').create();
    273  var fs = require('fs');
    274 +var cookiespath = '.iced_cookies';
    275 +var config = '';
    276  if (args.length === 1) {
    277      console.log('Try to pass some args when invoking this script!');
    278  } else {
    279 @@ -12,6 +14,7 @@ if (args.length === 1) {
    280        var filepath  = args[4];
    281        var plugins_file  = args[5];
    282        var search  = 'nix';
    283 +      var loginTimeout = '5000';
    284    }else{
    285      if (args.length === 7){
    286        var SACSID  = args[1];
    287 @@ -20,10 +23,200 @@ if (args.length === 1) {
    288        var filepath  = args[4];
    289        var search  = args[5];
    290        var plugins_file  = args[6];
    291 +      var loginTimeout = '5000';
    292      }
    293    }
    294  }
    295  
    296 +function validateEmail(email) {
    297 +    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,}))$/;
    298 +    return re.test(email);
    299 +}
    300 +
    301 +function quit(err) {
    302 +  phantom.exit(0);
    303 +}
    304 +if (validateEmail(SACSID)) {
    305 +  loadCookies(function() {
    306 +    if (config.SACSID == undefined || config.SACSID == '') {
    307 +      firePlainLogin(SACSID, CSRF);
    308 +    } else {
    309 +      addCookies(config.SACSID, config.CSRF);
    310 +      console.log('Using cookies to log in');
    311 +      afterCookieLogin();
    312 +    }
    313 +  });
    314 +}else {
    315 +  addCookies(SACSID, CSRF);
    316 +  afterCookieLogin(IntelURL, search);
    317 +}
    318 +
    319 +function loadCookies(callback) {
    320 +  if(fs.exists(cookiespath)) {
    321 +    var stream = fs.open(cookiespath, 'r');
    322 +
    323 +    while(!stream.atEnd()) {
    324 +      var line = stream.readLine().split('=');
    325 +      if(line[0] === 'SACSID') {
    326 +        config.SACSID = line[1];
    327 +      } else if(line[0] === 'csrftoken') {
    328 +        config.CSRF = line[1];
    329 +      } else {
    330 +        config.SACSID = '';
    331 +        config.CSRF = '';
    332 +      }
    333 +    }
    334 +    stream.close();
    335 +  }
    336 +  callback();
    337 +}
    338 +
    339 +function isSignedIn() {
    340 +  return page.evaluate(function() {
    341 +    return document.getElementsByTagName('a')[0].innerText.trim() !== 'Sign in';
    342 +  });
    343 +}
    344 +
    345 +function storeCookies() {
    346 +  var cookies = page.cookies;
    347 +  fs.write(cookiespath, '', 'w');
    348 +  for(var i in cookies) {
    349 +    fs.write(cookiespath, cookies[i].name + '=' + cookies[i].value +'\n', 'a');
    350 +  }
    351 +}
    352 +
    353 +function firePlainLogin(SACSID, CSRF) {
    354 +  page.open('https://www.ingress.com/intel', function (status) {
    355 +    page.evaluate(function () {
    356 +      localStorage.clear()
    357 +    });
    358 +    if (status !== 'success') {quit('unable to connect to remote server')}
    359 +    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='
    360 +    page.open(link, function () {
    361 +      login(SACSID, CSRF);
    362 +    });
    363 +  });
    364 +}
    365 +
    366 +function login(l, p) {
    367 +    if (document.querySelector('#timeoutError')){
    368 +        login(l, p)
    369 +        firePlainLogin(l, p)
    370 +    }
    371 +    waitFor({
    372 +        timeout: loginTimeout*2,
    373 +        check: function () {
    374 +            return page.evaluate(function() {
    375 +                if (document.querySelector('#gaia_loginform')) {
    376 +                    return true;
    377 +                }else{
    378 +                    return false;
    379 +                }
    380 +            });
    381 +        },
    382 +        success: function () {
    383 +            page.evaluate(function (l) {
    384 +                document.getElementById('Email').value = l;
    385 +            }, l);
    386 +            page.evaluate(function () {
    387 +                document.querySelector("#next").click();
    388 +            });
    389 +            window.setTimeout(function () {
    390 +                page.evaluate(function (p) {
    391 +                    document.getElementById('Passwd').value = p;
    392 +                }, p);
    393 +                if(document.querySelector("#next")){
    394 +                    page.evaluate(function () {
    395 +                        document.querySelector("#next").click();
    396 +                    });
    397 +                }else{
    398 +                    page.evaluate(function () {
    399 +                        document.querySelector("#signIn").click();
    400 +                    });
    401 +                }
    402 +                window.setTimeout(function () {
    403 +                    if (page.url.substring(0,40) === 'https://accounts.google.com/ServiceLogin') {
    404 +                        quit('login failed: wrong email and/or password');
    405 +                    }
    406 +
    407 +                    if (page.url.substring(0,40) === 'https://appengine.google.com/_ah/loginfo') {
    408 +                        page.evaluate(function () {
    409 +                            document.getElementById('persist_checkbox').checked = true;
    410 +                            document.getElementsByTagName('form').submit();
    411 +                        });
    412 +                    }
    413 +
    414 +                    if (page.url.substring(0,44) === 'https://accounts.google.com/signin/challenge') {
    415 +                        twostep = system.stdin.readLine();
    416 +                    }
    417 +                    window.setTimeout(afterPlainLogin(IntelURL, search), loginTimeout);
    418 +                }, loginTimeout)
    419 +            }, loginTimeout / 10);
    420 +        },
    421 +        error: function () {
    422 +            quit();
    423 +        }
    424 +    });
    425 +}
    426 +
    427 +function afterPlainLogin(IntelURL, search) {
    428 +  page.viewportSize = { width: '1280', height: '720' };
    429 +  page.open(IntelURL, function(status) {
    430 +    if (status !== 'success') {quit('unable to connect to remote server')}
    431 +    if (!isSignedIn()) {
    432 +      console.log("not logged in")
    433 +      quit();
    434 +    }
    435 +    setTimeout(function() {
    436 +		setupIITC()
    437 +        setTimeout(function() {
    438 +          setTimeout(function() {if (search != "nix") {searchfunc(search);}}, 1000);
    439 +            waitFor({
    440 +                timeout: 240000,
    441 +                check: function () {
    442 +                    return page.evaluate(function() {
    443 +                        if (document.querySelector('.map').textContent.indexOf('done') != -1) {
    444 +                            return true;
    445 +                        }else{
    446 +                            console.log('generateFakeOutput')
    447 +                            return false;
    448 +                        }
    449 +                    });
    450 +                },
    451 +                success: function () {
    452 +                  var startTime = new Date().getTime();
    453 +                  var interval = setInterval(function(){
    454 +                    if(new Date().getTime() - startTime > 5000){
    455 +                      hideDebris();
    456 +                      prepare('1280', '720');
    457 +                      main();
    458 +                      clearInterval(interval);
    459 +                      return;
    460 +                    }
    461 +                    console.log('generateFakeOutput')
    462 +                  }, 1000);
    463 +                },
    464 +                error: function () {
    465 +                  var startTime = new Date().getTime();
    466 +                  var interval = setInterval(function(){
    467 +                    if(new Date().getTime() - startTime > 5000){
    468 +                      hideDebris();
    469 +                      prepare('1280', '720');
    470 +                      main();
    471 +                      clearInterval(interval);
    472 +                      return;
    473 +                    }
    474 +                    console.log('generateFakeOutput')
    475 +                  }, 1000);
    476 +                }
    477 +            });
    478 +        }, "1000");
    479 +    }, "1000");
    480 +  });
    481 +}
    482 +
    483 +
    484 +
    485  function addCookies(sacsid, csrf) {
    486    phantom.addCookie({
    487      name: 'SACSID',
    488 @@ -46,11 +239,9 @@ function waitFor ($config) {
    489      $config._start = $config._start || new Date();
    490      if ($config.timeout && new Date - $config._start > $config.timeout) {
    491          if ($config.error) $config.error();
    492 -        if ($config.debug) console.log('timedout ' + (new Date - $config._start) + 'ms');
    493          return;
    494      }
    495      if ($config.check()) {
    496 -        if ($config.debug) console.log('success ' + (new Date - $config._start) + 'ms');
    497          return $config.success();
    498      }
    499      setTimeout(waitFor, $config.interval || 0, $config);
    500 @@ -69,95 +260,141 @@ function loadLocalIitcPlugin(src) {
    501      page.injectJs(src)
    502  }
    503  
    504 -addCookies(SACSID, CSRF);
    505 -afterCookieLogin(IntelURL, search);
    506 -
    507  function afterCookieLogin(IntelURL, search) {
    508 -  page.viewportSize = { width: '1920', height: '1080' };
    509 +  page.viewportSize = { width: '1280', height: '720' };
    510    page.open(IntelURL, function(status) {
    511      if (status !== 'success') {quit('unable to connect to remote server')}
    512 -    page.injectJs('https://code.jquery.com/jquery-3.1.1.min.js');
    513 +    if(!isSignedIn()) {
    514 +      if(fs.exists(cookiespath)) {
    515 +        fs.remove(cookiespath);
    516 +      }
    517 +      if(validateEmail(SACSID)) {
    518 +        page.deleteCookie('SACSID');
    519 +        page.deleteCookie('csrftoken');
    520 +        firePlainLogin(SACSID, CSRF);
    521 +        return;
    522 +      } else {
    523 +        quit('Cookies are obsolete. Update your config file.');
    524 +      }
    525 +    }
    526      setTimeout(function() {
    527 -        page.evaluate(function() {
    528 -            localStorage['ingress.intelmap.layergroupdisplayed'] = JSON.stringify({
    529 -              "Unclaimed Portals":Boolean(1 === 1),
    530 -              "Level 1 Portals":Boolean(1 === 1),
    531 -              "Level 2 Portals":Boolean((1 <= 2) && (8 >= 2)),
    532 -              "Level 3 Portals":Boolean((1 <= 3) && (8 >= 3)),
    533 -              "Level 4 Portals":Boolean((1 <= 4) && (8 >= 4)),
    534 -              "Level 5 Portals":Boolean((1 <= 5) && (8 >= 5)),
    535 -              "Level 6 Portals":Boolean((1 <= 6) && (8 >= 6)),
    536 -              "Level 7 Portals":Boolean((1 <= 7) && (8 >= 7)),
    537 -              "Level 8 Portals":Boolean(8 === 8),
    538 -              "DEBUG Data Tiles":false,
    539 -              "Artifacts":true,
    540 -              "Ornaments":true
    541 -            });
    542 -            var script = document.createElement('script');
    543 -            script.type='text/javascript';
    544 -            script.src='https://secure.jonatkins.com/iitc/release/total-conversion-build.user.js';
    545 -            document.head.insertBefore(script, document.head.lastChild);
    546 -        });
    547 -        loadIitcPlugin('http://iitc.jonatkins.com/release/plugins/canvas-render.user.js');
    548 -        var plugins = JSON.parse(fs.read(plugins_file));
    549 -        for(var i in plugins){
    550 -            var plugin = plugins[i];
    551 -            if(plugin.match('^[a-zA-Z]+://')){
    552 -                loadIitcPlugin(plugin);
    553 -            }else{
    554 -               loadLocalIitcPlugin(plugin);
    555 -            }
    556 -        }
    557 +    	setupIITC()
    558          setTimeout(function() {
    559 -            if (search != "nix") {
    560 -                page.evaluate(function(search) {
    561 -                    if (document.querySelector('#search')){
    562 -                      window.setTimeout(function() {
    563 -                        document.getElementById("search").value=search;
    564 -                        var e = jQuery.Event("keypress");
    565 -                        e.which = 13;
    566 -                        e.keyCode = 13;
    567 -                        $("#search").trigger(e);
    568 -                      }, 2000);
    569 -                      var checkExist = setInterval(function() {
    570 -                        if ($('.searchquery').length > 0) {
    571 -                            window.setTimeout(function() {$('.searchquery > :nth-child(2)').children()[0].click();}, 1000);
    572 -                            clearInterval(checkExist);
    573 -                        }
    574 -                      }, 100);             
    575 -                    }
    576 -                }, search);
    577 -            }
    578 +          if (search != "nix") {searchfunc(search);}
    579              waitFor({
    580 -                timeout: 120000,
    581 +                timeout: 240000,
    582                  check: function () {
    583                      return page.evaluate(function() {
    584                          if (document.querySelector('.map').textContent.indexOf('done') != -1) {
    585                              return true;
    586                          }else{
    587 +                            console.log('generateFakeOutput')
    588                              return false;
    589                          }
    590                      });
    591                  },
    592                  success: function () {
    593 -                    hideDebris();
    594 -                    prepare('1920', '1080');
    595 -                    main();
    596 +                  var startTime = new Date().getTime();
    597 +                  var interval = setInterval(function(){
    598 +                    if(new Date().getTime() - startTime > 5000){
    599 +                      hideDebris();
    600 +                      prepare('1280', '720');
    601 +                      main();
    602 +                      clearInterval(interval);
    603 +                      return;
    604 +                    }
    605 +                    console.log('generateFakeOutput')
    606 +                  }, 1000);
    607                  },
    608                  error: function () {
    609 -                    hideDebris();
    610 -                    prepare('1920', '1080');
    611 -                    main();
    612 +                  var startTime = new Date().getTime();
    613 +                  var interval = setInterval(function(){
    614 +                    if(new Date().getTime() - startTime > 5000){
    615 +                      hideDebris();
    616 +                      prepare('1280', '720');
    617 +                      main();
    618 +                      clearInterval(interval);
    619 +                      return;
    620 +                    }
    621 +                    console.log('generateFakeOutput')
    622 +                  }, 1000);
    623                  }
    624              });
    625 -        }, "5000");
    626 -    }, "5000");
    627 +        }, "1000");
    628 +    }, "1000");
    629    });
    630  }
    631  
    632 +function searchfunc(search){
    633 +  page.evaluate(function(search) {
    634 +    if (document.querySelector('#search')){
    635 +        window.addHook('search', function(query) {
    636 +          var checkExist = setInterval(function() {
    637 +            if (query.results.length > 0) {
    638 +              console.warn(query.results)
    639 +              map.fitBounds(query.results[0].bounds, {maxZoom: 17})
    640 +              clearInterval(checkExist);
    641 +            }
    642 +          }, 100);
    643 +        });
    644 +      setTimeout(function() {
    645 +        window.search.doSearch(search, true)
    646 +      }, 2000);
    647 +    }
    648 +  }, search);
    649 +}
    650 +
    651 +function setupIITC(){
    652 +    loadIitcPlugin('https://static.iitc.me/build/release/plugins/canvas-render.user.js');
    653 +    page.evaluate(function() {
    654 +        localStorage['ingress.intelmap.layergroupdisplayed'] = JSON.stringify({
    655 +          "Unclaimed Portals": true,
    656 +          "Level 1 Portals": true,
    657 +          "Level 2 Portals": true,
    658 +          "Level 3 Portals": true,
    659 +          "Level 4 Portals": true,
    660 +          "Level 5 Portals": true,
    661 +          "Level 6 Portals": true,
    662 +          "Level 7 Portals": true,
    663 +          "Level 8 Portals": true,
    664 +		      "Fields": true,
    665 +		      "Links": true,
    666 +		      "Resistance": true,
    667 +		      "Enlightened": true,
    668 +          "DEBUG Data Tiles":false,
    669 +          "Artifacts":true,
    670 +          "Ornaments":true
    671 +        });
    672 +        var script = document.createElement('script');
    673 +        script.type='text/javascript';
    674 +        script.src='https://static.iitc.me/build/test/total-conversion-build.user.js';
    675 +        document.head.insertBefore(script, document.head.lastChild);
    676 +    	localStorage['iitc-base-map'] = 'Google Roads';
    677 +    });
    678 +    var plugins = JSON.parse(fs.read(plugins_file));
    679 +    for(var i in plugins){
    680 +        var plugin = plugins[i];
    681 +        if(plugin.match('^[a-zA-Z]+://')){
    682 +            loadIitcPlugin(plugin);
    683 +        }else{
    684 +           loadLocalIitcPlugin(plugin);
    685 +        }
    686 +    }
    687 +}
    688 +
    689  function s(file) {
    690 +  console.log('SCREENSHOT')
    691    page.render(file);
    692 -  phantom.exit(0);
    693 +  var startTime = new Date().getTime();
    694 +  var startTime = new Date().getTime();
    695 +  var interval = setInterval(function(){
    696 +    if(new Date().getTime() - startTime > 5000){
    697 +      clearInterval(interval);
    698 +      phantom.exit(0);
    699 +      return;
    700 +    }
    701 +    console.log('doSomeOutput')
    702 +  }, 1000);
    703  }
    704  
    705  function hideDebris() {
    706 @@ -170,14 +407,14 @@ function hideDebris() {
    707        if (document.querySelector('#sidebartoggle'))             {document.querySelector('#sidebartoggle').style.display = 'none';}
    708        if (document.querySelector('#scrollwrapper'))             {document.querySelector('#scrollwrapper').style.display = 'none';}
    709        if (document.querySelector('.leaflet-control-container')) {document.querySelector('.leaflet-control-container').style.display = 'none';}
    710 +      if (document.querySelector('#portal_highlight_select')) {document.querySelector('#portal_highlight_select').style.display = 'none';}
    711      });
    712 -  }, 2000);
    713 +  }, 200);
    714  }
    715  
    716  function prepare(widthz, heightz) {
    717 -        window.setTimeout(function() {
    718 -          page.evaluate(function(w, h) {
    719 -            $("span:contains(' Google Roads')").prev().click();
    720 +    window.setTimeout(function() {
    721 +        page.evaluate(function(w, h) {
    722              var water = document.createElement('p');
    723              water.id='viewport-ice';
    724              water.style.position = 'absolute';
    725 @@ -188,10 +425,10 @@ function prepare(widthz, heightz) {
    726              water.style.width = w + 'px';
    727              water.style.height = h + 'px';
    728              document.querySelectorAll('body')[0].appendChild(water);
    729 -          }, widthz, heightz);
    730 -          var selector = "#viewport-ice";
    731 -          setElementBounds(selector);
    732 -        }, 4000);
    733 +        }, widthz, heightz);
    734 +        var selector = "#viewport-ice";
    735 +        setElementBounds(selector);
    736 +    }, 500);
    737  }
    738  
    739  
    740 @@ -241,10 +478,10 @@ function getDateTime(format) {
    741  }
    742  
    743  function addTimestamp(time) {
    744 -  page.evaluate(function(dateTime) {
    745 +  page.evaluate(function(dateTime, search) {
    746      var water = document.createElement('p');
    747      water.id='watermark-ice';
    748 -    water.innerHTML = dateTime;
    749 +    water.innerHTML = dateTime + ' - ' + search;
    750      water.style.position = 'absolute';
    751      water.style.color = '#3A539B';
    752      water.style.top = '0';
    753 @@ -255,9 +492,9 @@ function addTimestamp(time) {
    754      water.style.fontSize = '40px';
    755      water.style.opacity = '0.8';
    756      water.style.fontFamily = 'monospace';
    757 -    water.style.textShadow = 'rgb(3, 3, 3) 7px 5px 9px';
    758 +    water.style.textShadow = '0px 1px 8px rgba(150, 150, 150, 1)';
    759      document.querySelectorAll('body')[0].appendChild(water);
    760 -  }, time);
    761 +  }, time, search);
    762  }
    763  
    764  /**
    765 @@ -274,5 +511,5 @@ function main() {
    766      addTimestamp(getDateTime(0));
    767      file = filepath;
    768      s(file);
    769 -  }, 3000);
    770 +  }, 400);
    771  }
    772 diff --git a/screencap_intel.js b/screencap_intel.js
    773 index 3ef8afc..0696c0e 100644
    774 --- a/screencap_intel.js
    775 +++ b/screencap_intel.js
    776 @@ -2,6 +2,8 @@ var system = require('system')
    777  var args = system.args;
    778  var page = require('webpage').create();
    779  var fs = require('fs');
    780 +var cookiespath = '.iced_cookies';
    781 +var config = '';
    782  if (args.length === 1) {
    783      console.log('Try to pass some args when invoking this script!');
    784  } else {
    785 @@ -11,6 +13,7 @@ if (args.length === 1) {
    786        var IntelURL  = args[3];
    787        var filepath  = args[4];
    788        var search  = 'nix';
    789 +      var loginTimeout = '10000';
    790    }else{
    791      if (args.length === 6){
    792        var SACSID  = args[1];
    793 @@ -18,12 +21,203 @@ if (args.length === 1) {
    794        var IntelURL  = args[3];
    795        var filepath  = args[4];
    796        var search  = args[5];
    797 +      var loginTimeout = '10000';
    798      }
    799    }
    800  }
    801  
    802 -addCookies(SACSID,CSRF);
    803 -afterCookieLogin(IntelURL, search);
    804 +function validateEmail(email) {
    805 +    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,}))$/;
    806 +    return re.test(email);
    807 +}
    808 +
    809 +function quit(err) {
    810 +  phantom.exit(1);
    811 +}
    812 +
    813 +if (validateEmail(SACSID)) {
    814 +  loadCookies(function() {
    815 +    if (config.SACSID == undefined || config.SACSID == '') {
    816 +      firePlainLogin(SACSID, CSRF);
    817 +    } else {
    818 +      addCookies(config.SACSID, config.CSRF);
    819 +      console.log('Using cookies to log in');
    820 +      afterCookieLogin();
    821 +    }
    822 +  });
    823 +}else {
    824 +  addCookies(SACSID, CSRF);
    825 +  afterCookieLogin(IntelURL, search);
    826 +}
    827 +
    828 +function firePlainLogin(SACSID, CSRF) {
    829 +  page.open('https://www.ingress.com/intel', function (status) {
    830 +    page.evaluate(function () {
    831 +      localStorage.clear()
    832 +    });
    833 +    if (status !== 'success') {quit('unable to connect to remote server')}
    834 +
    835 +    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='
    836 +
    837 +    page.open(link, function () {
    838 +      login(SACSID, CSRF);
    839 +    });
    840 +  });
    841 +}
    842 +
    843 +function loadCookies(callback) {
    844 +  if(fs.exists(cookiespath)) {
    845 +    var stream = fs.open(cookiespath, 'r');
    846 +
    847 +    while(!stream.atEnd()) {
    848 +      var line = stream.readLine().split('=');
    849 +      if(line[0] === 'SACSID') {
    850 +        config.SACSID = line[1];
    851 +      } else if(line[0] === 'csrftoken') {
    852 +        config.CSRF = line[1];
    853 +      } else {
    854 +        config.SACSID = '';
    855 +        config.CSRF = '';
    856 +      }
    857 +    }
    858 +    stream.close();
    859 +  }
    860 +  callback();
    861 +}
    862 +
    863 +function isSignedIn() {
    864 +  return page.evaluate(function() {
    865 +    return document.getElementsByTagName('a')[0].innerText.trim() !== 'Sign in';
    866 +  });
    867 +}
    868 +
    869 +function storeCookies() {
    870 +  var cookies = page.cookies;
    871 +  fs.write(cookiespath, '', 'w');
    872 +  for(var i in cookies) {
    873 +    fs.write(cookiespath, cookies[i].name + '=' + cookies[i].value +'\n', 'a');
    874 +  }
    875 +}
    876 +
    877 +function login(l, p) {
    878 +    if (document.querySelector('#timeoutError')){
    879 +        login(l, p)
    880 +        firePlainLogin(l, p)
    881 +    }
    882 +    waitFor({
    883 +        timeout: 240000,
    884 +        check: function () {
    885 +            return page.evaluate(function() {
    886 +                if (document.querySelector('#gaia_loginform')) {
    887 +                    return true;
    888 +                }else{
    889 +                    return false;
    890 +                }
    891 +            });
    892 +        },
    893 +        success: function () {
    894 +            page.evaluate(function (l) {
    895 +                document.getElementById('Email').value = l;
    896 +            }, l);
    897 +            page.evaluate(function () {
    898 +                document.querySelector("#next").click();
    899 +            });
    900 +            window.setTimeout(function () {
    901 +                page.evaluate(function (p) {
    902 +                    document.getElementById('Passwd').value = p;
    903 +                }, p);
    904 +                if(document.querySelector("#next")){
    905 +                    page.evaluate(function () {
    906 +                        document.querySelector("#next").click();
    907 +                    });
    908 +                }else{
    909 +                    page.evaluate(function () {
    910 +                        document.querySelector("#signIn").click();
    911 +                    });
    912 +                }
    913 +//                 page.evaluate(function () {
    914 +//                     document.getElementById('gaia_loginform').submit();
    915 +//                 });
    916 +                window.setTimeout(function () {
    917 +                    if (page.url.substring(0,40) === 'https://accounts.google.com/ServiceLogin') {
    918 +                        quit('login failed: wrong email and/or password');
    919 +                    }
    920 +
    921 +                    if (page.url.substring(0,40) === 'https://appengine.google.com/_ah/loginfo') {
    922 +                        page.evaluate(function () {
    923 +                            document.getElementById('persist_checkbox').checked = true;
    924 +                            document.getElementsByTagName('form').submit();
    925 +                        });
    926 +                    }
    927 +
    928 +                    if (page.url.substring(0,44) === 'https://accounts.google.com/signin/challenge') {
    929 +                        twostep = system.stdin.readLine();
    930 +                    }
    931 +
    932 +                    //       if (twostep) {
    933 +                    //         page.evaluate(function (code) {
    934 +                    //           document.getElementById('totpPin').value = code;
    935 +                    //         }, twostep);
    936 +                    //         page.evaluate(function () {
    937 +                    //           document.getElementById('submit').click();
    938 +                    //           document.getElementById('challenge').submit();
    939 +                    //         });
    940 +                    //       }
    941 +                    window.setTimeout(afterPlainLogin(IntelURL, search), loginTimeout);
    942 +                }, loginTimeout)
    943 +            }, loginTimeout / 10);
    944 +        },
    945 +        error: function () {
    946 +            quit();
    947 +        }
    948 +    });
    949 +}
    950 +
    951 +function afterPlainLogin(IntelURL, search) {
    952 +  page.open(IntelURL, function(status) {
    953 +    if (status !== 'success') {quit('unable to connect to remote server')}
    954 +
    955 +    if (!isSignedIn()) {
    956 +      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.');
    957 +      quit();
    958 +    }
    959 +    setTimeout(function() {
    960 +        storeCookies();
    961 +        waitFor({
    962 +            timeout: 240000,
    963 +            check: function () {
    964 +                return page.evaluate(function() {
    965 +                    if (document.querySelector('#percent_text').textContent.indexOf('90') != -1) {
    966 +                        if (!document.getElementById("loading_msg").style.display){
    967 +                            return true;
    968 +                        }else{
    969 +                            return false;
    970 +                        }
    971 +                    }else{
    972 +                        return false;
    973 +                    }
    974 +                });
    975 +            },
    976 +            success: function () {
    977 +                page.evaluate(function() {
    978 +                    document.querySelector("#filters_container").style.display= 'none';
    979 +                });
    980 +                hideDebris();
    981 +                prepare('1920', '1080', search);
    982 +                main();
    983 +            },
    984 +            error: function () {
    985 +                page.evaluate(function() {
    986 +                    document.querySelector("#filters_container").style.display= 'none';
    987 +                });
    988 +                hideDebris();
    989 +                prepare('1920', '1080', search);
    990 +                main();
    991 +            }
    992 +        });
    993 +    }, "5000");
    994 +  });
    995 +}
    996  
    997  function addCookies(sacsid, csrf) {
    998    phantom.addCookie({
    999 @@ -59,10 +253,22 @@ function waitFor ($config) {
   1000  function afterCookieLogin(IntelURL, search) {
   1001    page.open(IntelURL, function(status) {
   1002      if (status !== 'success') {quit('unable to connect to remote server')}
   1003 -
   1004 +    if(!isSignedIn()) {
   1005 +      if(fs.exists(cookiespath)) {
   1006 +        fs.remove(cookiespath);
   1007 +      }
   1008 +      if(validateEmail(SACSID)) {
   1009 +        page.deleteCookie('SACSID');
   1010 +        page.deleteCookie('csrftoken');
   1011 +        firePlainLogin(SACSID, CSRF);
   1012 +        return;
   1013 +      } else {
   1014 +        quit('Cookies are obsolete. Update your config file.');
   1015 +      }
   1016 +    }
   1017      setTimeout(function() {
   1018          waitFor({
   1019 -            timeout: 120000,
   1020 +            timeout: 240000,
   1021              check: function () {
   1022                  return page.evaluate(function() {
   1023                      if (document.querySelector('#percent_text').textContent.indexOf('90') != -1) {