All posts by Inder

I am a programmer. I have Bachelors in Computer Science from Tufts University. I currently work full-time at Boston University developing their websites.

Best way to avoid ads in exercise apps

I’ve found that the best way to avoid ad-infested apps for exercising is to use official apps from popular brands. They’re better because they bother you again and again about non-exercise-related matters (ads, social sharing, etc)

For example the following apps are great alternatives to popular ad-filled apps:

  1. Nike Run Club – Much better than C25k (Couch-to-5k).
  2. J&J 7 Minute Workout – Alternative to 7 Minute Workout.

Composer stuck on installing private GitHub repos

I was trying to install some GitHub repos as dependencies using composer. Composer kept getting stuck on installing the private ones.


"repositories": [
        "type": "vcs",
        "url": ""
"require-dev": {
    "inderpreet99/private": "1.0.1"


$ composer install
Loading composer repositories with package information
The "" file could not be downloaded (HTTP/1.1 404 Not Found)
install [--prefer-source] [--prefer-dist] [--dry-run] [--dev] [--no-dev] [--no-custom-installers] [--no-autoloader] [--no-scripts] [--no-progress] [--no-suggest] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--ignore-platform-reqs] [--] []...


  1. Go to your GitHub profile.
  2. Under Developer Settings > Personal access tokens, generate a new token.
  3. In cli:
    $ export GITHUB_ACCESS_TOKEN="gibberisheaab78ab18285b9something"
    $ composer config -g $GITHUB_ACCESS_TOKEN

Composer should work much more smoothly now.

Webmin bug copying SSL certificates to Virtualmin panel

When you generate a SSL certificate for an nginx site through the Virtualmin interface for a virtual (sub-)server, the button “Copy to Webmin” incorrectly triggers the “Copy to Usermin” feature.

On the other hand, the Webmin interface to generate the SSL certificate also fails, because it does not allow for generation for nginx hosts (only Apache hosts).


  1. Generate the SSL certificate using Let’s Encrypt in Virtualmin for the virtual (sub-)server.
  2. Run the following command as root to copy the certificate to Webmin:
    virtualmin install-service-cert --domain --service webmin

Add Lets Encrypt for Webmin/Virtualmin Panel itself

Are you getting a “challenge did not pass” error? Can’t find a matching hostname for your Webmin panel to generate Let’s Encrypt certificates to?

The trick is that Lets Encrypt only works with Apache. Most Webmin/Virtualmin panels are running on miniserv Perl scripts on port 10000. We must follow the following steps:

1. Create a virtual server (or sub server) for the matching domain in Virtualmin.
2. Go to Webmin > Webmin Configuration > SSL Encryption > Let’s Encrypt
3. Request Certificate for “Apache virtual host matching hostname”. Set renewal for 12 months!

Reload problems for Raspberry Pi as a Digital Signage solution

There are quite a few tutorials out there to turn Raspberry Pi into Digital Signage or Kiosk solutions. I’ve used elalemanyo GitHub gist to run Chromium browser for my Digital Signage needs. It provides lots of options and combines various sources of information. There are options for other browsers on that page.

The gist does not address a way to automatically reload/recover from page/chrome/connection errors. You can use the following two extensions to recover from these problems:

1. Oh No You Didn’t extension will automatically reload tabs that have crashed (Aw Snap! He’s Dead Jim etc.). Handy for Kiosk mode where access is limited. This helps recover from memory related problems (quite often the Raspberry Pi’s are limited by memory or CPU).

2. Autorefresh on Error will auto-refresh a page after 60 seconds if page did not load. This is handy for any webpage that changes often and needs to be refreshed. And for places where the WiFi coverage may not be ideal, especially on boot.

Unrar split RARs on Windows using Cygwin

Sometimes out of dire circumstances one may download a huge set of rars. Unraring all the scene release files in split rar format in each separate directory with their separate subtitles (idx/sub files) is a cumbersome task.

  1. Install unrar from
  2. cd into the base season directory using cygwin.
  3. Unrar recursively:
    find /path/to/dir-of-rars -iname "*.rar" -exec sh -c 'dir=`dirname {}` && echo "$dir" && unrar -o- e "{}" $dir' \;
  4. You may need to run this multiple times to catch the rars that the rars may create.

Install latest Chromium on Raspberry Pi B+

Update on December 26, 2016: Latest Raspbian can install Chromium Browser by just doing: apt-get install chromium-browser. No need to download debs or run gdebi. Making this post obsolete.

Installing the latest Chromium browser on Raspberry Pi B models is a hassle. Although the following tricks work on the other Raspberry Pi models. I wanted to target Raspberry Pi B+ with this tutorial since it requires some special steps.

  1. Download the latest .deb package files:
  2. Ensure you have gdebi:
    sudo apt-get install gdebi-core
  3. Install the packages one by one (install libgcrypt11 first!!!):
    sudo gdebi libgcrypt11
    sudo gdebi chromium-codecs-ffmpeg-extra
    sudo gdebi chromium-browser
  4. Run:

WordPress as a Service

At two recent WordPress conferences, WPCampus 2016 and WordCamp Boston 2016, I gave a talk along with Andrew Bauer on using WordPress as a Service (WPaaS) in a higher education setting.

In this talk, we covered the organizational and technical benefits of running a multi-network, multi-site WordPress as the primary CMS at Boston University. We highlighted specific strategies, including organizational policies, development workflows and team structure that allow us to serve over a million users per month. We’re here to help dispel the notion that a centralized approach to WordPress can’t successfully be implemented in higher ed.



Kodi’s Pulsar errors starting up

If you are seeing the following Pulsar errors, check the possible solutions:

Problem: Trying to launch Pulsar

21:31:27 T:2440  NOTICE: [] 2015-02-03 21:31:27  INFO  btservice        Starting DHT...
21:31:27 T:2440  NOTICE: [] 2015-02-03 21:31:27  INFO  btservice        Starting LSD...
21:31:27 T:2440  NOTICE: [] 2015-02-03 21:31:27  INFO  btservice        Starting UPNP...
21:31:27 T:2440  NOTICE: [] 2015-02-03 21:31:27  INFO  btservice        Starting NATPMP...
21:31:27 T:4984  NOTICE: Thread LanguageInvoker start, auto delete: false
21:31:27 T:4984  NOTICE: -->Python Interpreter Initialized<--
21:31:27 T:4984  NOTICE: http://localhost:65251/
21:31:28 T:4984   ERROR: EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
                                             - NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
                                            Error Type: <class 'urllib2.URLError'>
                                            Error Contents: <urlopen error [Errno 10061] No connection could be made because the target machine actively refused it>
                                            Traceback (most recent call last):
                                              File "C:\Users\TVComputer\AppData\Roaming\Kodi\addons\\", line 6, in <module>
                                              File "C:\Users\TVComputer\AppData\Roaming\Kodi\addons\\resources\site-packages\pulsar\", line 72, in run
                                                data = _json(url)
                                              File "C:\Users\TVComputer\AppData\Roaming\Kodi\addons\\resources\site-packages\pulsar\", line 40, in _json
                                                with closing(urllib2.urlopen(url)) as response:
                                              File "C:\Program Files (x86)\Kodi\system\python\Lib\", line 127, in urlopen
                                                return, data, timeout)
                                              File "C:\Program Files (x86)\Kodi\system\python\Lib\", line 404, in open
                                                response = self._open(req, data)
                                              File "C:\Program Files (x86)\Kodi\system\python\Lib\", line 422, in _open
                                                '_open', req)
                                              File "C:\Program Files (x86)\Kodi\system\python\Lib\", line 382, in _call_chain
                                                result = func(*args)
                                              File "C:\Program Files (x86)\Kodi\system\python\Lib\", line 1214, in http_open
                                                return self.do_open(httplib.HTTPConnection, req)
                                              File "C:\Program Files (x86)\Kodi\system\python\Lib\", line 1184, in do_open
                                                raise URLError(err)
                                            URLError: <urlopen error [Errno 10061] No connection could be made because the target machine actively refused it>
                                            -->End of Python script error report<--
21:31:29 T:4548   ERROR: XFILE::CDirectory::GetDirectory - Error getting plugin://
21:31:29 T:4548   ERROR: CGUIMediaWindow::GetDirectory(plugin:// failed
21:31:29 T:764  NOTICE: Thread BackgroundLoader start, auto delete: false

Wait for Pulsar to start up. It usually takes about 1-2 minutes for it to load after Kodi has been enabled.

Problem: Deleting missing stale files

17:08:01 T:139736123422464 NOTICE: [] Deleting stale files set(['C:\\path\\to\\file\\filename.mp4'])


  1. Go to %APPDATA%\Kodi\ directory.
  2. Delete the cache directory.
  3. Delete the userdata\addon_data\\cache directory

WordPress failing to insert post into the database

I was recently trying to insert imported data into WordPress. When trying to insert it into WordPress using wp_insert_post, I was receiving the following error:

Could not insert post into the database

It turns out that I was trying to insert data in a non-utf8 encoding, whereas WordPress uses UTF8 internally. All I had to do was run the following PHP function to convert it over to UTF8:

$post_content = iconv('ISO-8859-1','UTF-8', $post_content)