14
\$\begingroup\$

Your mission, should you chose to accept it, is to beat everyone else to the review tab so you get a chance to help out.

This is a problem I've been running into lately. I go over to review tab, find a post awaiting review, select it, and then after my page loads, it's already been reviewed.

And since this site doesn't have new posts rolling in every second, a post isn't put into the queue for a while.

Or so it seems....

I don't have the time to be hunched over at my desk, constantly clicking "refresh" in hope that I'll catch a post coming in before someone else.

To aid this problem, I created a simple web-based application that does this for me.

As long as I have the webpage that I created open, I'll be sent notifications the second a post is put into the queue.

File tree

Everything is in one directory, as shown below:

review_listener

====> dummy.html

====> get_html.php

====> index.html

====> main.js

====> start_server.sh

Code

dummy.html

There is actually nothing in this file, to start. Read on to find the purpose of this file.

get_html.php

This, using the command line, calls the curl command and uses the > to change STDOUT to be dummy.html. This way, the main.js file can easily interact with the HTML.

<?php
    exec("curl https://codereview.stackexchange.com/review > dummy.html");
?>

If you are familiar with JavaScript, you are probably wondering why I didn't just open the link with window.open in the JavaScript file. I had already try that, but for some reason it wasn't working, and I had already made this before thinking of just doing it with JavaScript. (Yes, this code does work).

index.html

Nothing interesting here. Kind of pointless to post, but I'd probably get closed if I didn't.

<!DOCTYPE html>
<html>
    <head>
        <script src = "main.js"></script>
    </head>
    <body>
    </body>
</html>

main.js

Here is where the fun happens!

var xhr;

function GETPHP() {
    xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXOBject("Microsoft.XMLHTTP");
    xhr.open("GET", "http://localhost:8000/get_html.php", true);
    xhr.send();
}

function handleHTML() {
    var newhtml = window.open("http://localhost:8000/dummy.html");
    newhtml.onload = function () {
        var nums = newhtml.document.getElementsByClassName("dashboard-num");
        for (var i = 0; i < nums.length; i++) {
            if (parseInt(nums[i].innerHTML, 10) > 0) {
                sendNotification();
                newhtml.close();
                break;
            }
            console.log("Number " + i + " is " + nums[i].innerHTML);
        }
        newhtml.close();
    }
}

function sendNotification() {
    //http://stackoverflow.com/questions/2271156/chrome-desktop-notification-example
    if (Notification.permission !== "granted") {
        Notification.requestPermission();
    }
    var notif = new Notification("CODE RED: POST IN QUEUE!!!", {
        body: "You must be quick before it gets Jamalized! Or worse!"
    });
    notif.onclick = function () {
        window.open("https://codereview.stackexchange.com/review");
    }
}
window.setInterval(function () {
    GETPHP();
    handleHTML();
}, 10000); // ten seconds

The above code does the following:

  1. Tells the PHP file to load the HTML into the dummy.html file

  2. Opens up the dummy.html file

  3. Reads the queue quantity values

  4. If there is a post in the queue, send a notification and go to 5

  5. Else, wait about 10 seconds and go back to 1

start_server.sh

This isn't that really interesting, either.

#!/bin/sh

php -S localhost:8000

Concerns

  • In the main.js file, I am constantly opening and closing a tab. This was the easiest way I think of doing it, but easy isn't always efficient; is there a more efficient way to do this?

  • Is my code portable? Mainly, do most people use a version of PHP that has the built in server, and do most browsers support the Notification object?

  • In order from greatest to least, below is my knowledge of the languages used:

    1. JavaScript

    2. HTML

    3. PHP

    4. Shell

That being said, are there some practices I should be following with these languages that I missed?

Any other recommendations of any sort are also welcome.

Disclaimer:

If you do happen to try and run this code (and you are successful), you may notice that you will either...

  1. Get a notification when there are no posts in the queue

  2. Not get a notification when there is a post in the queue

This is not a bug. When the code connects to the Code Review server, it is only given a preview of the review section. This preview is less frequently updated than if you were to manually log on to Code Review; nothing I can control

The code works as I would like it.

\$\endgroup\$
8
\$\begingroup\$

I don't really see the point to create with PHP a file that then you have to read in javascript. Can't you just return the content of dummy.html when you make your Ajax request, which will give you a direct access to the data you want in javascript ?

Two other (minor) things :

  • I would execute the analysis of the HTML on the PHP side, there are great functions to do so. Just because it will be executed server-side, so presumably faster (even if, in that case it's the same computer)
  • setInterval is bad : what will happen if your Ajax call is slow to execute (like so slow that it'll take more than 10s) ? A setTimeOut with a recursive call to itself would be better I think (that way, you're sure that your functions did end before calling them back again).
| improve this answer | |
\$\endgroup\$
7
\$\begingroup\$

You have one problem in your HTML - you need a <title>Page Title Here</title> tag in the <head> group.

<!DOCTYPE html>
<html>
    <head>
        <script src = "main.js"></script>
        <title>Page Title</title>
    </head>
    <body>
    </body>
</html>

You can validate your HTML at the W3C validator

I do not know JavaScript, but you do use good style format: putting spaces around your operators, using braces around one-liner loops and if statements, correct indentation and good spacing, and using the var keyword in front of variable declarations.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Also the lang attribute should be defined in the <html> tag. Moreover, charset attribute must be defined in a meta element inside the head element. \$\endgroup\$ – Abandoned Account Feb 22 '15 at 13:03
6
\$\begingroup\$

Every 10 seconds

xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXOBject("Microsoft.XMLHTTP");
xhr.open("GET", "http://localhost:8000/get_html.php", true);
xhr.send();

This is the body of the GETPHP function (which should, by the way, follow the correct naming conventions).

This is called every 10 seconds.

This address has to be found every 10 seconds.

This address has to be connected to every 10 seconds.

You can imagine that this must not be the most efficient thing, right? I'm not quite sure if this would work as I expect, but I think it would be more memory-efficient to create a single XMLHttpRequest object and to open and send it every time rather than creating it.

The XMLHttpRequest object is an entire service for HTTP requests. Therefore, creating them and destroying them constantly might be inefficient when it comes to memory and transfer.


Open... close! Open... close!

This application is quite annoying. If I want to run this in the same browser that I am using to do other things, every ten seconds, my browser is forced over to the new tab. The only fix for me was to use a completely new browser.

Also, as you mention, having to constantly open and close a browser tab must not be the efficient (you're probably correct).

How about, instead of creating a destroying a new tab, you simply refresh the already existing tab? Now you won't experience the tab jumping and you won't have to worry about the creation and dispersion of the system resources for a tab.

It will probably also result in faster code, considering it does not have to constantly create a new tab and set an event listener to it.


| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.