Thursday, May 28, 2015

Tv Show Tracker - On Heroku

I recently decided that I should start testing out my tv show tracker website out in "the real web" instead of just local development. So to help me along I chose to use Heroku, which is a PaaS - platform as a service. The advantage of using a PaaS is that they manage your actual box, upgrades, security, etc. for you. All you have to do is build and deploy your site according to their guidelines.

After going through their documentation of how to deploy a Scala application, I have successfully deployed tv-show-tracker on Heroku. However, this was not as straight-forward as the documentation made it out to be - especially when I'm using spray instead of just a quick HTTP server like their example uses. So I thought I'd go through some of the things I had to do to get my site up and running on their platform.

First, lucky for me, I already had my site fully utilizing sbt so I had most of the config and dependencies working as they want you to. However, I did have to add an sbt plugin:
 addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.8.0")  
After that was added, I had to add the following to my build.sbt file:
 import NativePackagerKeys._  
 packageArchetype.java_application  
Heroku utilizes this native packager and foreman to run Scala applications which is not something I was doing when I would run it locally.

Secondly, I had issues connecting to my PostgreSQL database. They went through some of the steps, however I felt some things were lacking. In the end, my database connection looks like:
 val dbUri = new URI(System.getenv("DATABASE_URL"))  
 val username = dbUri.getUserInfo.split(":")(0)  
 val password = dbUri.getUserInfo.split(":")(1)  
 val db = Database.forURL(s"jdbc:postgresql://${dbUri.getHost}:${dbUri.getPort}${dbUri.getPath}", driver = "org.postgresql.Driver", user = username, password = password)  
This connection setup uses slick, where their example just had a regular database connection.

Next, I had issues seeing the data in my database. I was lucky enough to come across this stack overflow question which helped me solve my problem - look at my data on my local install of pgadmin. Now, the accepted answer is what I used to get it working, however not all steps are properly documented in that answer.

To get all of the information needed to fill out the pgadmin server, you first need to run:
 heroku config  
If you have the database add-on installed, it will spit out a database url that we need. We just need to know how to decipher this long url and break it into the individual parts:
 DATABASE_URL: postgres://user:password@server:port/database  
Once we know how the url is broken down (example above), you just plug each part into pgadmin (like the SO answer says) and you can see your data on your local install of pgadmin.

Lastly, I had issues with my site properly binding to the host and port and being able to hit the url from my computer.

For the port, I tried putting in 8080 and 5000 (from the example) but neither seemed to work. I eventually found this documentation which explains that I need to get the port from a system variable - PORT.

I also had issues with the hostname I was supposed to connect to. I tried "localhost" and my site's url but neither of those worked. Then I came across this SO answer which showed I needed to use "0.0.0.0". This allows the app to bind to the localhost and accept incoming traffic from my sites Heroku url.
So, in the end my connection looks like:
 val myPort = Properties.envOrElse("PORT", "8080").toInt // for Heroku compatibility  
 IO(Http) ? Http.Bind(service, interface = "0.0.0.0", port = myPort)  
This allows my app to get the proper port from Heroku or use a default of 8080 if I'm running locally.

All in all, this turned out pretty well seeing that I was able to go from my local setup to running on Heroku in just a few hours. There were a few hiccups along the way, but it seems like other people have ran into the issues I experienced before and I was able to use the answers given to them.

Saturday, May 16, 2015

Tv Show Tracker - Basic Pages

As I noted on my previous post, I am currently working on a site to track the tv shows I watch. I have been working quite a bit, have a few main pages working, and thought I should write an update.

URLs

  • /
  • /index 
  • /shows
  • /searchshow
  • /show
    • Request parameters:
      • showName
  • /searchseason
  • /season
    • Request parameters:
      • showName
      • number
  • /notfound
/
This is the base url. It just re-directs to /index.

/index
The main landing page of the site. On this page the user can choose to list all shows, search a specific show, or search a specific season of a show

/shows
Lists all shows recorded in the database. Each show is a link to the individual show's page which displays extra information about the show itself.

/searchshow
This page allows the user to search for a specific show. If a show is found, the user is directed the show's page. If the show is not found, a not found page is displayed.

/show
Displays information about a specific show. The show name is passed in via a request parameter.

/searchseason
This page allows the user to search for a specific season in a show. If the season is found, the user is directed to the season's page. If the season is not found, a not found page is displayed.

/season
Displays information about a specific season of a shot. The show name and number are passed in via request parameters.

/notfound
Indicates to the user that the information requested was not found.

Next Steps

  • Episodes. These need to be added to individual seasons so that they can be tracked as watched.
  • Watched indicator. There needs to be an indicator on each episode, season, and show to let the user know if they've watched it already.
  • Currently watching. There needs to be a way for the user to indicate which show they are currently watching. This way they can easily check when they've watched a particular episode and see which episode is next to watch.
  • Data. The site needs to add the ability to insert episodes, season, and shows. Currently the few shows and seasons are hard-coded. The user needs to be able to add an episode, season, and show from the site. If it is already in the database, the site will indicate that to the user.