Malayalam TV

Like most of the older folk in my ethnic community, my grandparents enjoy watching Malayalam television programming. They had jumped on the satellite bandwagon a few years ago and got good mileage out of it. However, at the end of 2011, Asianet, one of the primary channels they watch, moved from Insat 2E to Intelsat 17. The shift to the more westerly satellite had the unfortunate consequence of removing coverage from the eastern seaboard of Australia.

A lot of disappointed Malayalees in Sydney, Melbourne and Brisbane had to find alternatives for getting their Malayalam TV fix. My grandparents found their saviour in BomTV, which provided live steaming via the Internet albeit on a subscription basis. This required a Roku (or Android) device, which was provided with the initial subscription to a package. The streaming quality wasn’t as good as satellite and the device would need to occasionally buffer, but it was adequate.

Recently, my grandparents needed to replace their TV and they ended up purchasing a smart TV with Internet browsing. Also, through my grandmother’s exploratory searching, they found that they could view Malayalam (along with other Indian language) TV content online using Bharat Channels. While it wasn’t real-time TV, they could select what they wanted to watch, whenever they wanted to watch, and it was free and without ads. Poking around, I noticed the website simply pointed to YouTube for all their content. I’m unsure if it is indeed the Indian TV channels themselves posting the content (as opposed to a third-party) but either way, it’s probably a good monetisation strategy for somebody.

The Bharat Channels website is obviously designed for a desktop (and not a TV) and adds a lot of visual noise. In order to streamline their viewing experience, I created a simple website that serves up the same YouTube content, but packaged in a more user-friendly way: Malayalam TV.

Using PHP and Twitter Bootstrap (for a responsive design), the script reads a specified YouTube channel’s RSS feed and displays the content as easy to click thumbnails. The thumbnails link to a full screen version of the video. Surprisingly, an iPad’s Safari browser requires a different link: http://www.youtube.com/embed/{id} vs. http://www.youtube.com/v/{id} while an iPhone doesn’t. I also had to use CSS media queries to lock the dimensions of the thumbnails, since certain videos have quite long titles. I did look into CSS’s text-overflow: ellipsis options, but this doesn’t work across multiple lines. While there are several JavaScript truncation libraries, in trying to be as minimal as possible, I just went for the quick and crude approach. This theme also carried over into the CSS, where only used CSS from Twitter Bootstrap was included.

See the code on GitHub.

Coloured directory listings in PowerShell

By default, PowerShell outputs drab directory listings. Unfortunately, there’s no built in solution to turning on colour, but it is possible with a few steps.

  1. This StackOverflow post gets us most of the way there. Towards the bottom of the question is some code that enables colourised output. I’ve modified it to suit my purposes (see below). This code should be put in your profile (see $profile to find the location).
  2. As noted, the code depends on the New-CommandWrapper cmdlet from the Powershell Cookbook. In my PowerShell profile directory, I’ve created a Scripts directory as a sibling to the regular Modules directory and put the cmdlet there.
  3. Ensure New-CommandWrapper.ps1 is unblocked (right click, Properties, Unblock) and in your PATH. If using the Scripts directory, you can put $env:Path += ";$(Split-Path $profile)\Scripts" in your profile.
  4. Using Set-ExecutionPolicy, ensure your execution policy is set to RemoteSigned or Unrestricted.
  5. Start a new shell, type dir or ls and enjoy.

As mentioned, I’ve modified the code in the StackOverflow post to suit my needs:

  • Cyan instead of Magenta directories. Magenta hurt my eyes.
  • Ignoring colouring text files separately as yellow. I have a lot of text files using different extensions and colouring text files didn’t provide any benefit.
  • Removed Perl, Python and Ruby extensions from executables. I don’t use Perl or Python and I have more Ruby code as part of a Rails app than standalone scripts.
  • Adjusted column spacing.
  • Don’t output a length for directories. It doesn’t show in the screenshot, but it displayed a length of 1 for directories.
  • Add coloured file count along with total file size at bottom.
  • Override both dir and ls aliases.
  • Renamed functions according to PowerShell verb-noun conventions.

The code that goes in your profile is:

New-CommandWrapper Out-Default -Process {
  $regex_opts = ([System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
  $compressed = New-Object System.Text.RegularExpressions.Regex(
    '\.(zip|tar|gz|rar|jar|war)$', $regex_opts)
  $executable = New-Object System.Text.RegularExpressions.Regex(
    '\.(exe|bat|cmd|msi|ps1|psm1|vbs|reg)$', $regex_opts)

  if(($_ -is [System.IO.DirectoryInfo]) -or ($_ -is [System.IO.FileInfo]))
  {
    if(-not ($notfirst))
    {
      Write-Host "`n    Directory: " -noNewLine
      Write-Host "$(pwd)`n" -foregroundcolor "Cyan"
      Write-Host "Mode        Last Write Time       Length   Name"
      Write-Host "----        ---------------       ------   ----"
      $notfirst=$true
    }

    if ($_ -is [System.IO.DirectoryInfo])
    {
      Write-Host ("{0}   {1}                {2}" -f $_.mode, ([String]::Format("{0,10} {1,8}", $_.LastWriteTime.ToString("d"), $_.LastWriteTime.ToString("t"))), $_.name) -ForegroundColor "Cyan"
    }
    else
    {
      if ($compressed.IsMatch($_.Name))
      {
        $color = "DarkGreen"
      }
      elseif ($executable.IsMatch($_.Name))
      {
        $color =  "Red"
      }
      else
      {
        $color = "White"
      }
      Write-Host ("{0}   {1}   {2,10}   {3}" -f $_.mode, ([String]::Format("{0,10} {1,8}", $_.LastWriteTime.ToString("d"), $_.LastWriteTime.ToString("t"))), $_.length, $_.name) -ForegroundColor $color
    }

    $_ = $null
  }
} -end {
  Write-Host
}

function Get-DirSize
{
  param ($dir)
  $bytes = 0
  $count = 0

  Get-Childitem $dir | Foreach-Object {
    if ($_ -is [System.IO.FileInfo])
    {
      $bytes += $_.Length
      $count++
    }
  }

  Write-Host "`n    " -NoNewline

  if ($bytes -ge 1KB -and $bytes -lt 1MB)
  {
    Write-Host ("" + [Math]::Round(($bytes / 1KB), 2) + " KB") -ForegroundColor "White" -NoNewLine
  }
  elseif ($bytes -ge 1MB -and $bytes -lt 1GB)
  {
    Write-Host ("" + [Math]::Round(($bytes / 1MB), 2) + " MB") -ForegroundColor "White" -NoNewLine
  }
  elseif ($bytes -ge 1GB)
  {
    Write-Host ("" + [Math]::Round(($bytes / 1GB), 2) + " GB") -ForegroundColor "White" -NoNewLine
  }
  else
  {
    Write-Host ("" + $bytes + " bytes") -ForegroundColor "White" -NoNewLine
  }
  Write-Host " in " -NoNewline
  Write-Host $count -ForegroundColor "White" -NoNewline
  Write-Host " files"

}

function Get-DirWithSize
{
  param ($dir)
  Get-Childitem $dir
  Get-DirSize $dir
}

Remove-Item alias:dir
Remove-Item alias:ls
Set-Alias dir Get-DirWithSize
Set-Alias ls Get-DirWithSize