trying to set up a bash script and applet for expressvpn [SOLVED]

All Gurus once were Newbies
Forum rules
There are no such things as "stupid" questions. However if you think your question is a bit stupid, then this is the right place for you to post it. Please stick to easy to-the-point questions that you feel people can answer fast. For long and complicated questions prefer the other forums within the support section.
Before you post please read how to get help
Post Reply
dondondon
Level 1
Level 1
Posts: 7
Joined: Tue Jan 16, 2018 4:12 pm

trying to set up a bash script and applet for expressvpn [SOLVED]

Post by dondondon » Tue Jan 16, 2018 4:39 pm

I'm following these instructions from https://joshua14.homelinux.org/blog/?p=2318

The title reads "How I Automated My ExpressVPN Connection Under Ubuntu" and it was published in October 2016, so I can guess right here might be part of my problem, but I'm a total newb, so :shrug:

The end result I'm looking for is an applet that lets me know I'm connected to the vpn, and tells me when I'm not.

OK, here are the instructions:
When you list the countries that you can connect to, there is a “Y” next to some of the items. This means these countries/locations are “recommended” for best speed. They differ from the “smart” connection option in that the smart connection will always be the country you reside in, although a different IP address.
I thought it would be good so that when I login to my Ubuntu machine, it connects to a randomly selected VPN country which has the “recommended” “Y” next to it. Since I don’t use Unity under Ubuntu but Cinnamon (much better, IMHO) I’d also like to display the country I’m connected to as a Desklet in my top desktop panel.

Here is the bash script which does this on boot.

Code: Select all

#!/bin/bash
expressvpn refresh
expressvpn list | tail -n+3 | column -ts $'t' | sed 's/   */:/g' > data.tmp
cat data.tmp | while read LINE
do
        if [ `echo $LINE | tail -c 2` == 'Y' ]; then
                TEMP=`echo $LINE | grep : | awk -F: '{print $1}'`
                echo "$TEMP" >> array.tmp
        fi
done
ARRAY_SIZE=`wc -l array.tmp | awk {'print $1'}`
RND_VPN=`shuf -i 1-$ARRAY_SIZE -n 1`
VPN=`sed "${RND_VPN}q;d" array.tmp`
rm -f data.tmp
rm -f array.tmp
expressvpn connect $VPN
The last bit is showing this information in Cinnamon as an applet. I don’t know much about writing JavaScript applets apart from they’re written in JavaScript as the Cinnamon documentation for this is super-weak, but I found a simple network status applet which is basically a refreshing label and that will do. All this does is put the output from the “expressvpn status” command into a label and displays it. Simple applets are composed from two files, the JavaScript JS file and a JSON descriptor file. Here are my horrible hacked together versions.
applet.js

Code: Select all

const Applet = imports.ui.applet;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const GLib = imports.gi.GLib;
const UUID = "expressvpn@jon";
const REFRESH_INTERVAL = 10

function log(message) {
    global.log(UUID + '#' + log.caller.name + ': ' + message);
}

function logError(error) {
    global.logError(UUID + '#' + logError.caller.name + ': ' + error);
}

function MyApplet(orientation) {
    this._init(orientation);
}

MyApplet.prototype = {
    __proto__: Applet.TextApplet.prototype,
    _init: function (orientation) {
        Applet.TextIconApplet.prototype._init.call(this, orientation);
        try {
            this.set_applet_icon_name("emblem-web");
            this.set_applet_tooltip(_("ExpressVPN Node location."));
            this.set_applet_label("...");
        }
        catch (error) {
            logError(error);
        }
        this.refreshLocation();
},

    refreshLocation: function refreshLocation() {
        let [res, out] = GLib.spawn_command_line_sync(" expressvpn status ")
        let out = String(out).replace("n", "");
        let out = String(out).trim();
        //let out = String(out).replace(/ /g, "-");
        //let out = String(out).replace(/   /g, " ");
        this.set_applet_label('VPN: ' + out + '');
        Mainloop.timeout_add_seconds(REFRESH_INTERVAL, Lang.bind(this, function refreshTimeout() {
            this.refreshLocation();
        }));
    }
};

function main(metadata, orientation) {
    let myapplet = new MyApplet(orientation);
    return myapplet;
}
metadata.json

Code: Select all

{
    "dangerous": true,
    "description": "Shows ExpressVPN Location",
    "name": "ExpressVPNStatus",
    "uuid": "expressvpn@jon"
}
Both these files go in the directory “$HOME/.local/share/cinnamon/applets/expressvpn@jon” as the directory is “applet_name@author” format. You can then add the applet as normal in Cinnamon to a panel.
so, I made the script executable, created a scripts directory in my home folder, added it to the PATH variable, moved the script to that folder. not sure if that part worked, but the script works...

the problem is the applet, which I get an error when trying to add to my taskbar

errors from glass.log:

<----------------
Extension.prototype._init@/usr/share/cinnamon/js/ui/extension.js:155:13
Extension@/usr/share/cinnamon/js/ui/extension.js:116:5
loadExtension@/usr/share/cinnamon/js/ui/extension.js:449:25
onEnabledAppletsChanged@/usr/share/cinnamon/js/ui/appletManager.js:236:13
---------------->
error t=2018-01-16T20:31:09.042Z [Applet "expressvpn@jon"]: Error importing applet.js from expressvpn@jon
error t=2018-01-16T20:31:09.042Z Could not load applet expressvpn@jon

not sure which errors come from this in .xsession-errors so I dropped them in pastebin

https://pastebin.com/xN36WyX0


Hopefully I submitted all of the relevant information and someone can help me. I'm a newish linux user. Much more user friendly than 15 years ago when I first tried it out. I love mint, but it's all quite confusing to me. I'm not horrible at following instructions, but the linux rabbithole is deep and wide. any assistance will be greatly appreciated, since expressvpn hasn't come up with this feature themselves, yet (for the applet, which is the part I really care about)

Thank you.
Last edited by dondondon on Tue Jan 16, 2018 10:39 pm, edited 1 time in total.

blockhead47
Level 2
Level 2
Posts: 86
Joined: Wed Jun 15, 2016 4:50 pm
Location: Chicago, IL, USA

Re: trying to set up a bash script and applet for expressvpn

Post by blockhead47 » Tue Jan 16, 2018 5:51 pm

I had to modify the applet.js for newer versions of Cinnamon. Try the one below"

Code: Select all

const Applet = imports.ui.applet;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const GLib = imports.gi.GLib;
const UUID = "expressvpn@jon";
const REFRESH_INTERVAL = 5

function log(message) {
    global.log(UUID + '#' + log.caller.name + ': ' + message);
}

function logError(error) {
    global.logError(UUID + '#' + logError.caller.name + ': ' + error);
}

function MyApplet(orientation) {
    this._init(orientation);
}

MyApplet.prototype = {
    __proto__: Applet.TextApplet.prototype,
    _init: function (orientation) {
        Applet.TextIconApplet.prototype._init.call(this, orientation);
        try {
            this.set_applet_icon_name("emblem-web");
            this.set_applet_tooltip(_("ExpressVPN Connection Status."));
            this.set_applet_label("...");
        }
        catch (error) {
            logError(error);
        }
        this.refreshLocation();
},

    refreshLocation: function refreshLocation() {
        let [res,out3] = GLib.spawn_command_line_sync(" expressvpn status ");
        let out2 = String(out3).replace("n", "");
        let out = String(out2).trim();
        this.set_applet_label('VPN: ' + out + '');
        Mainloop.timeout_add_seconds(REFRESH_INTERVAL, Lang.bind(this, function refreshTimeout() {
            this.refreshLocation();
        }));
    }
};

function main(metadata, orientation) {
    let myapplet = new MyApplet(orientation);
    return myapplet;
}

dondondon
Level 1
Level 1
Posts: 7
Joined: Tue Jan 16, 2018 4:12 pm

Re: trying to set up a bash script and applet for expressvpn

Post by dondondon » Tue Jan 16, 2018 10:27 pm

yay! thank you!. I works now :-D

Post Reply

Return to “Newbie Questions”