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.

Monday, April 27, 2015

Tv Show Tracker

I watch a lot of tv shows and keeping track of which shows/seasons/episodes I have watched can be a daunting task if I don't stay on top of it. At any one time I am watching more than 1 show, but sometimes as much as 5 different shows in a given week. To help myself keep track of these things, I have been using a Google Doc Excel sheet which tracks my shows, seasons, and episodes I have been watching.

This is obviously not ideal because I have to do a lot of manual work and it's very archaic. So, for this reason, I have started tv-show-tracker. The idea behind this project is to make a more robust solution than all of my manual labor to keep my items in order. Right now this is in the very early stages, however the end goal could help me out quite a bit. I would eventually like to be able to:

  • Enter a show I would like to watch
  • Have it import all of the seasons and episodes
  • Keep track of which shows I'm currently watching and what episode I'm on
  • Allow multiple users to use this based on a login
Seeing that this site is an "easier" project (database layer, a couple of endpoints to hit, and a presentation layer) I decided to use a full Scala stack. Not only will this help me learn Scala better, but also get used to the open source projects Scala has because I'm choosing to use true Scala projects - not Java ones. The projects I've chosen to use on this site are:

As noted above, this is in very early stages of development, however that doesn't mean I am not making good progress. So far I have successfully wired up all of these projects and have the proof of concept working:
  • URL endpoints with request parameters - e.g."Shows"
  • Parse the request parameters and search the database
  • Return the "Show" and its "Seasons"
  • Render the results to the user
There's obviously a lot of work still to go, but now that I have a proof of concept working the rest should start to fall into place quicker - I just need to nail down the database schema and then work up the stack.

Friday, April 24, 2015

Scala Shell

I've recently been working on a new side project - scala-shell. As one might guess, this is a shell written in Scala. The idea behind this side project is to help further my Scala knowledge and dive into some more advanced topics such as:

  • Creating a GUI
  • Files and directories
  • Parsing user input
  • Processes
  • Packaging using sbt
I haven't had a lot of time to work on scala-shell, however I currently have the following items completed:
  • Creating a GUI
  • Packaging using sbt
  • Parsing user input
  • A few basic commands
    • exit
    • pwd
    • ls
  • Printing an error on invalid input

I realize that there's still a long ways to go to make this a "usable" shell, however I feel that it's coming along quite nicely and am happy with my current progress.

Friday, February 6, 2015

Pi-Temperature

Raspberry Pi's are a great little tool for learning. Software people can learn a little hardware and hardware people can learn a little software. I recently got a Raspberry Pi B+ kit and have been messing around with it lately to learn a little hardware.

My goal was to attach temperature sensors and have the Pi report back the temperature to me.

So, I went out and bought the Vktech DS18b20 sensors and attached them to a GPIO port. Once, the sensors have been connected, you need to login and run the following 2 commands to have Linux setup and probe them:

 sudo modprobe w1-gpio  
 sudo modprobe w1-therm  

Now, once those commands are ran, the temperatures will show up in following files:

 /sys/bus/w1/devices/w1_bus_master1/<serial id>/w1_slave  

where <serial id> is the serial id of the sensor itself. An example of one of these files is:

 4d 01 4b 46 7f ff 03 10 d8 : crc=d8 YES  
 4d 01 4b 46 7f ff 03 10 d8 t=20812  

Now, in that file, the Celsius temperature is actually the last little bit, 20812 - it just needs to be divided by 1000 and you have your Celsius temperature of 20.8.

Great, it's now working. Linux is probing the sensor and reporting it to a file which I can read and see. It works, but not that practical. At this point I wanted to see if I could automate this process so I didn't have to manually read the file each time I want to know the temperature.

Meet pi-temperature, a Java library I wrote to solve this exact problem. It probes all attached sensors for me at a given interval (defaults to 1 min) and can report the temperatures of each sensor back to the user. It utilizes spring boot to startup a local Tomcat instance for a web server and has several REST urls attached:

 /sensors/list  
 /alerts/list  
 /alerts/setOn/<name>  
 /alerts/setOff/<name>  
 /alerts/update/<name>  

The /sensors/list is the primary endpoint which reads all of the sensors and reports back the temperatures in both Celsius and Fahrenheit. The /alerts endpoints are currently a work in progress and another post will be coming soon with their features.

Specific instructions on how to build, run, and more thorough instructions can be found on the pi-temperature project's README.

Saturday, October 11, 2014

Scala Simple Build Tool

So, recently as I was working through my scala book, we got to the first chapter where we used 3rd party dependencies - the testing chapter. Now, for the simple examples in the chapter I just downloaded the jars needed and put them on my classpath in Eclipse and got everything working just fine. However, I was interested in looking for a dependency manager for scala and that's when I stumbled up the scala sbt project. With this finding, I decided to mimic the tests done in the testing chapter, but this time use scala sbt to manage my dependencies and put them on the classpath for me (I've pushed this small project to my github account).

Setting Up First Project In Eclipse


After I installed sbt, geting my first project up and running was not trivial so I wanted to walk through the steps I did to get a project from initial commit in github to fully working.
Note: I copied a lot of steps from a SO answer, however it was not exactly the same so I wanted to type up the steps I did.
  • Create your new repo on Github and clone it somewhere locally
  • Add the sbt eclipse plugin to your list of global sbt plugins
    • Now this step was a little confusing for me because the instructions were for *NIX style setups. They say to just add the line:
    •  addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.5.0")  
      To the file:
    •  ~/.sbt/0.13/plugins/plugins.sbt  
      
    • However, I'm working on Windows so obviously this path doesn't exist. Though, eventually I figured it out and needed to add it to the local user's file. So, in my case the file was located at:
    •  C:\Users\Dan\.sbt\0.13\plugins\plugins.sbt  
      
  • Once you add this plugin, open a command prompt to where you cloned your repo and type the following:
  •  sbt eclipse  
    
    • This will generate all of the eclipse project, classpath, and other various files needed to work properly in Eclipse
  • Import the project into Eclipse and start coding:
    • File --> Import --> General --> Existing Projects into Workspace
And that's it, now you can start working on your scala project inside of eclipse and get all of the helpfulness from the scala Eclipse plugin.

build.sbt


Once you have your project initialized and ready to go in Eclipse, it's time to make our build.sbt file. This file serves the same purpose as the file "pom.xml" for maven projects - it defines your jar name, version, dependencies, etc etc. Now, my build.sbt is very simple, however there a lot of different things you can do in this file and they are explained on the sbt site.

Adding Dependencies


Now, adding dependencies to your project is clearly defined on the sbt site, however there was one issue I ran into that I wanted to write down. By default, Eclipse will not reload the dependencies when you add them to your build.sbt file. Instead, you need to reload the Eclipse definition with the sbt plugin we added earlier. This is done by just typing a couple of commands into a command prompt and refreshing the Eclipse project - the steps to do this are listed on this SO answer.

Change SBT Download Location


By default, sbt will download jars to folder in the user's directory, in my case it was:
 C:\Users\Dan\.ivy2\cache  
However, I did not want my downloaded jars to reside there because that meant each user would have their own copies of all of the scala jars used. So, I found yet another SO answer that showed me how to change the download location. I simply had to edit my sbtconfig.txt file, which was located at - C:\Program Files (x86)\sbt\conf\sbtconfig.txt - and had to add the following 2 lines:
 -Dsbt.ivy.home=S:\SBTRepo  
 -Divy.home=S:\SBTRepo  
So now all jars will download to the folder - S:\SBTRepo - for all users and not to each user's individual local files.

Now, all of these steps might seem like a lot, but it really didn't take that long - there was definitely more investigate than implementation. It's just that this was my first time building a dependency-managed scala project so inevitably took the longest to get properly setup. And once all of these steps were done, my scala project was up and running perfectly in Eclipse and I was able to test everything properly on the command line.

Wednesday, August 27, 2014

My First Website

Today I took down my wedding website (code still available on GitHub) and wanted to reflect on the experience.

Now, creating a website for me was actually pretty difficult. Not only was this my first website I've created, but I also don't do user interface work/design. I am a back-end programmer that likes to work with databases, business logic, the occasional command line program, etc. - but never do I do any front-facing UI work. I just personally don't like working on them. However, my wife wanted me to make a website seeing that I'm a programmer and thought it would be a good challenge. So, I ended up making my own website completely from scratch: all of the coding, hosting the domain, running the server, everything.

Hosting

For hosting my website, I chose to go through Digital Ocean. I chose to host my site with them due to a few reasons:
  • It was cheap - I was only paying $10/month for 1GB ram, 30GB SSD, and 2TB network.
  • It was extremely easy to use - Their  console was super simple to understand and to manage my "droplet" with.
  • Their user guides are incredible - This is the main reason why I went with them. They have tons and tons of guides that are super easy to follow. Some of the better ones I used were:
    • Initial server setup - Which covered everything from the very first login to how to properly secure your system by removing the root login and changing the ssh port.
    • Setting up a LAMP server - Teaches you how to install Apache, MySQL, and PHP on a Linux box.
    • Fail2Ban - Shows how to properly configure fail2ban so your system is not continually tried to be compromised.

Coding

As I stated before, I wrote the entire website from scratch. To accomplish this, I used basic HTML5, CSS, and Javascript. Though, I did get help with some of the coding by using some popular libraries:
  • Twitter Bootstrap - Helped with overall design of the site. Also, does auto-adjusting of the page so viewing on different devices (laptop, phone, tablet) all look and feel the same.
  • Galleria - A simple to use picture gallery. This library was fantastic. The setup was super simple, the documentation great, and has a lot of specific configuration options to choose from. Also, it only took me about 2 hours total from initial download until I had working on my live site.
  • Google Forms - I used this for my RSVP. It's a form where I had all of the RSVP questions: are you coming, what do you want for dinner, etc. The awesome part of this tool is that it stores its answer directly to your Google Drive so you don't have to worry about losing any responses.

Final Thoughts

All in all this was a great project to work on because not only did I get the satisfaction of creating my first website, but all of my guests were able to see it as well. However, if I were to do this again, I would re-consider about where I host my site. Now I know that I said I loved Digital Ocean, and I did, however running an entire server for just a simple website seemed like overkill to me. I've heard about PAAS sites such as Heroku, Google App Engine, AWS Elastic Beanstalk, etc. but I didn't want to learn how all of that worked for such a simple goal - to launch a HTML site. Though, I feel if I did a more complex site with java, I would definitely look at one of these before running my own server again.

Wednesday, April 16, 2014

More Scala Projects

As I stated in my last post, my buddy Josh and are I currently working on small little scripts/projects while learning new languages. He is choosing to learn Ruby while I am learning Scala. Since that last post we have done a few more scripts/projects:
Count Vowels
This problem involved reading a file, counting all of the vowels, and then printing out a report. Currently, this program works completely as expected and I'm very happy with my solution.

Example execution using itself as the input file:
 S:\Workspaces\Github\scala-projects\Text>scala VowelCount.scala VowelCount.scala  
 Vowel: A    Count: 29    Percentage: 0.2437%  
 Vowel: E    Count: 32    Percentage: 0.2689%  
 Vowel: I    Count: 19    Percentage: 0.1597%  
 Vowel: O    Count: 31    Percentage: 0.2605%  
 Vowel: U    Count: 8    Percentage: 0.0672%  

Palindrome
As one might expect, this challenge was to determine if a file/string is a palindrome or not; palindrome meaning it's spelled the same was forwards as it is backwards (e.g. "racecar"). Now, to make this challenge a little more difficult, Josh and I added some "bonus point opportunities":
  • Ignore white space so "racecar" and "race car" both return true
  • Ignore case so "Race car" and "race car" both return true
  • If the whole string is not a palindrome, find the largest substring which is a palindrome
I conquered this challenge by breaking this down into a few steps and then putting them altogether:
  • Read the whole text into a string and then remove anything which is not a standard character
  • Find all substrings of the character string
  • Order the substrings by length
  • Loop through them until a palindrome is found, indicating this is the largest substring which is a palindrome
Example execution using itself as the input file:
 S:\Workspaces\Github\scala-projects\Text>scala Palindrome.scala Palindrome.scala  
 Largest substring of file which is a palindrome:  
 srevers  

Zip File Maker
This problem was not necessarily a typical problem but more of a learning challenge. As stated it was: given a file or directory, zip up that file or directory. Now, I say this is more of a learning challenge because there's really not much to solve, but a lot to learn. For my solution, if a directory is given as input, I recursively found all of the sub-directories and files and added them to the zip as well.

Example executing using a file and directory as input:
 S:\Workspaces\Github\scala-projects\Files>scala Zip.scala ..\Text\ Zip.scala  
 Adding file S:\Workspaces\Github\scala-projects\Text\Palindrome.scala to zip.  
 Adding file S:\Workspaces\Github\scala-projects\Text\README.md to zip.  
 Adding file S:\Workspaces\Github\scala-projects\Text\VowelCount.scala to zip.  
 Adding file S:\Workspaces\Github\scala-projects\Text\WordCount.scala to zip.  
 Adding file S:\Workspaces\Github\scala-projects\Files\Zip.scala to zip.  

The zip is created in the local directory called "output.zip" and uses the full path of each file when adding them and zipping them up.

Word Count
This problem was just an extension of the "Vowel Count" we did, except this time we counted all words in a file. Now, this problem was up for more individual interpretation than the others because each person could have their own rules on hyphenated words, contractions, punctuation, etc. Though, for my solution the approach I took was:
  • Read all of the lines from the input file
  • Remove all punctuation that had a space on either side of it; this allows hyphenated and contractions to remain
  • Remove all periods - this could be extended to include commas, question marks, and exclamation marks in the future
  • Count how many times each word was found
  • Write to a properties file
Now, I know the solution approach I made is not as elegant as it can be, but it's a start and maybe when I get better with Scala, I'll come back later and spruce it up a little.

Example execution using itself as the input file:
 S:\Workspaces\Github\scala-projects\Text>scala WordCount.scala WordCount.scala  

This will put the output of all the words to their total count in a file called "wordcount.properties":
 S:\Workspaces\Github\scala-projects\Text>cat wordcount.properties  
 #Wed Apr 16 17:56:23 CDT 2014  
 properties=1  
 punctuation=1  
 new=4  
 java.io.FileOutputStream=1  
 import=3  
 read.")=1  
 \\\\p{Punct}*=1  
 //=1  
 HashMap[String,=1  
 line=1  
 "))=1  
 properties.store(output,=1  
 throw=1  
 (line=1  
 line.split("=1  
 from=1  
 provide=1  
 +\==1  
 \==6  
 else=1  
 all=2  
 v.toString)=1  
 IllegalArgumentException("Must=1  
 file=1  
 scala.collection.mutable.HashMap=1  
 1=2  
 lines)=1  
 output=1  
 val=5  
 ((k,v)=1  
 1)=1  
 \!\==1  
 ").toLowerCase()=1  
 wordCounts=1  
 wordCounts)=1  
 line.replaceAll("=1  
 Properties()=1  
 (\!wordCounts.contains(word))=1  
 "=3  
 lines=1  
 if=2  
 }=2  
 |\\\\.",=1  
 "."=1  
 {=2  
 properties.setProperty(k,=1  
 trimmedLine=1  
 null)=1  
 by=1  
 (args.size=1  
 for=3  
 surrounded=1  
 (word=1  
 and=1  
 Removing=1  
 scala.io.Source.fromFile(args(0)).getLines=1  
 FileOutputStream("wordcount.properties")=1  
 <-=3  
 Int]()=1  
 java.util.Properties=1  
 wordCounts(word)=2  
 a=1  
 to=1  
 =20  

So ya, that's what Josh and I have been up to. If you want more up to date information on how our projects are going you can always look at our code on our github repos: