Tasks
Task #1 (75 points)
The purpose of this first task is to ensure that you understand the basics of HTML, can write some by hand, and can link together pages.
For the first task, you will set up a basic web page that will be your portfolio for this course and perhaps beyond. Under your Local/HTML-Documents directory, create a directory called WebApps. Make an index.html file in that directory. Make sure that everything is world-readable and that you can see the pages you put up when you are done.
That index.html file should be a basic HTML file with links to your tasks and projects for this class. After the things for this class, feel free to put links to any other web-based projects you might have worked on that you can link to.
You will also create an AboutMe.html file and have a link to it in index.html. As the name implies, this file should include a description of you that you would want potential employers to see. So, highlight your experience and what you have done.
For this task, none of this needs to look good. That will be task #2 when you use CSS to make these pages so they don't look horrible.
Task #2 (75 points)
This task aims to verify that you understand the basics of CSS and can add it to a page.
Add CSS to the pages you wrote for Task #1 so that they look better. Do this by putting a directory under WebApps called styles and making a tasks.css file in there that has the CSS you want to apply to what you created in Task #1. Then, edit those files so they use that stylesheet.
Task #3 (100 points)
The purpose of this task is to make sure that you understand the basics of JavaScript programming and how you can use it in a website to modify the DOM.
Make a page with an interactive table from Dougstats and link to it on your main WebApps page. There are several different tables on the links at the site. You can pick one. The table should have at least three columns and 30 rows, but it could be much bigger. You get 50 points for a page where you can sort the columns by different values. You can get the additional 50 by adding other features, like possibly filtering data by text a user enters. Note that interface and functionality matter here for full points.
The way I expect you to do this is to copy the data from the table you are working with into a JavaScript file, and then work with it there. I am not expecting you to pull the data through an Ajax call, as we haven't learned about those yet.
You only get points for the code you create here. Using libraries written by others doesn't count. Note that JQuery is a library, so if you use JQuery, you aren't going to get full points.
Task #4 (100 points)
The purpose of this task is to make sure that you know how to create a Canvas in JavaScript and add user interactivity with event handling.
For this task, I want you to create a page with a canvas that does something interesting and interactive. A simple game would be a good example of this. I wrote an old-style Tron Lightcycles myself. Whatever you write can interact through the mouse, the keyboard, or both. As before, this needs to be YOUR code, even if it is simple. If I find that you pull significant amounts of code from another source, you will get a 0 on this task.
Notes on Tasks 5-11
All the tasks below here are done with Play. You should add all the code to the GitHub Classroom repository I have set up for your tasks. Make sure you commit so I can look at the code if I choose to. I strongly recommend not deleting old tasks when you do new ones. Simply add additional routes and associated code for each task. That way, when you bring up a server at the end, it will have all the tasks present and working.
Task #5 (100 points)
The purpose of this task is to make sure that you can use the Play Framework to build a Web 1.0-style interactive application.
For this task, you will make a message board using Play. The message board should support two types of messages: those directed to another user and those visible to all users. There should be a login with the ability to create new users. Once a user is logged in, they should be put on a screen that shows both the personal messages sent to them and the general messages. That page will have the functionality to add new messages. The first page should include your name in the header.
Instead of storing the data in a database, for this task, I want you to store it in the memory of your app in a model that is properly synchronized. Note that this implementation means that if you take the application down, none of the messages will be remembered when it comes back up. That is fine for now. I want your app to start with two users: "web" with the password "apps" and "mlewis" with the password "prof". There should also be one message from mlewis to web and one visible to all users.
If you want to run your application in dev mode using a different port, specify the port number after run. For example, in sbt, use "run 9009". If you pick a port number from the range I assigned, you will never have a conflict with other students. You can also edit the http.port setting in application.conf to be the port you want to use.
To submit, you will need to deploy your Play application, and I want you to run it on the Pandora machine that I have assigned to you or run it in Google Cloud. The page I grade should have a link I can follow for grading purposes. Here are the steps to run the Play server in normal mode on the Pandora machines with the screen command so it keeps running when you log off. Also, you should push your code to the tasks repository because I will look for it there.
Execute dist in sbt, copy the resulting zip file somewhere in your userspace, and unzip it. I will note that the "stage" command in sbt makes the file the Heroku runs and can probably also be used here, but I haven't tested this myself. If you plan to host on the lab machines, I recommend doing this on a lab machine.
Go into the directory created by unzipping.
Do an ls -l, and you will see a bin directory and a conf directory.
Verify that conf/application.conf has the setting you want. (You can set these in your project before you run sbt dist, so you don't have to set them every time you deploy.) You have to change the play.http.secret.key setting if you haven't already done so. The allowed hosts value is set to ".". If you want extra security, you can change this to the full name and port number of the Pandora machine you are running on. You should add a line that says "http.port=###" where "###" has been replaced by a port number in the range I have assigned to you. Note that some of these changes can be made in the conf.application.conf file before doing a dist and will be remembered so you don't have to repeat this on each deployment.
Run screen. It will look like you just cleared your terminal, but you are in a new shell that can stay there when you log out. If you have connected to screen before, consider doing a screen -ls to see if your previous screen session is running and reconnect to it. (If you have only one session, reconnect with screen -dRR.)
In the bin directory is an executable. Run that executable: "bin/executable-name"
If you changed the port in conf/application.conf, run it with no arguments. If you didn't set the port, give a command line argument like -Dhttp.port=9001 with your port number.
You should see it print stuff saying the server is running. Connect to it with a browser to test it. The URL should be something like "http://pandora01.cs.trinity.edu:9001/messages". Make sure it works.
Hit Ctrl-a followed by d. This will disconnect you from screen so you can log out. For more information on screen, I suggest this cheatsheet. Note that you can reconnect to that screen session with "screen -dRR" if you realize you need to kill the server and change something.
If you want to do a cloud deployment to the Google Cloud, execute the following instructions.
Set up to be done once.
Create your Google Cloud account.
Turn on the Compute Engine API.
Create an instance.
You can lower RAM to 2GB to save money.
Under Firewall, allow HTTP traffic.
SSH into your instance and install the needed software that isn't there by default.
sudo apt-get install openjdk-17-jdk
sudo apt-get install unzip
Each time you deploy, do the following.
Connect to the instance with ssh. This will pop up a window.
If you have done this before, I recommend killing the old process and deleting all the old files before you copy up the new ones. Use ls -l to see your files. Use rm -rf to remove the old versions.
Execute dist in sbt and copy the resulting zip file onto your Google Cloud instance. The Web interface has an upload button that can do this, otherwise, you can set up the gcloud command line and use their scp command.
Unzip the file.
Verify that conf/application.conf has the setting you want. (You can set these in your project before you do a sbt dist, so you don't have to set them every time you deploy.) You have to change the play.http.secret.key setting if you haven't already done so. The allowed hosts is set to ".". If you want extra security, you can change this to the full name and port number of the Pandora machine you are running on. You should add a line that says "http.port=###" where "###" has been replaced by 80, the default HTTP port. Note that some of these changes can be made in the conf.application.conf file before doing a dist and will be remembered so you don't have to repeat this on each deployment.
Run screen. It will look like you just cleared your terminal, but you are in a new shell that can stay there when you log out. If you have connected to screen before, could you run screen -ls to see if your previous screen session is running and reconnect to it? (If you have only one session, reconnect with screen -dRR.)
In the bin directory is an executable. Run that executable: "sudo bin/executable-name"
If you changed the port in conf/application.conf, run it with no arguments. If you didn't set the port, give a command line argument like -Dhttp.port=9001 with your port number.
You should see it print stuff saying the server is running. Connect to it with a browser to test it. Find the "External IP" for your instance. If your external IP were 34.27.221.144 then the URL should be something like "http://34.27.221.144/messages". Make sure it works.
Hit Ctrl-a followed by d. This will disconnect you from screen so you can log out. For more information on screen, I suggest this cheatsheet. You can reconnect to that screen session with "screen -dRR" if you need to kill the server and change something.
(If we don't get cloud credits.) Send me an email letting me know it is up. I will respond after I have graded it. You can then stop the instance so it doesn't charge you as much.
You can take down your application by connecting to screen and hitting Ctrl-C. Hit Ctrl-D to close the screen session. You need to do this to bring up a new version. (Unless you are on Google Cloud and you stopped your instance.)
Task #6 (100 points)
The goal of this task is to make sure that you can write automated tests for your Play app.
Write automated tests for your site from task #5. I want you to do this using ScalaTest.
I want you to have standard unit tests for all the methods in your data model. For most people, there are five such methods. (See https://www.playframework.com/documentation/2.9.x/ScalaTestingWithScalaTest#Unit-Testing-Models)
I also want you to make a Selenium browser-based test and have it test the main functionality of your app. (See https://www.playframework.com/documentation/2.9.x/ScalaFunctionalTestingWithScalaTest#Testing-with-a-web-browser)
When you are done, make sure that you push to your repository, as I will be grading these by looking at the code and pulling your repository to run the tests. Note that I have observed conflicts between React and Selenium in the past. You should comment out the React libraries from the main view if you run into such problems.
Task #7 (125 points)
This task will make sure that you can use web sockets.
Using web sockets, make a page with a canvas where each person on the page shows up as some small sprite or drawn image that they can control with the arrow keys. Everyone should see everyone else moving around. They should not leave a path; you should see them where they are on the initial page load.
Task #8 (100 points)
The goal of this task is to make sure you know how to create a SPA using React.
Make your message board use Ajax/web sockets and React. I suggest Ajax for this.
Task #9 (125 points)
This task will assess your ability to use databases in your web apps.
Redo task #5/8 using Slick for the message storage. Deploy this on the Pandora machine or to Google Cloud. Let me know if you use a Pandora machine so I can set up a database for you.
Google Cloud Instructions
If you want to host on the Google Cloud, here are some instructions and links to Google Cloud pages. I got a little test app running with a public IP.
First, you will need to set up your database. I have links below for this.
Note that first, you create an instance. This will be a VM that runs the PostgreSQL server for you to connect to. You can put multiple databases on a single instance.
Once you have an instance set up, you will create the database and add a user to it. The password you give to that user will be needed for connecting in the later instructions.
Make sure your instance is in the same region as your VM.
Configure it with a public IP.
Create instance - https://cloud.google.com/sql/docs/postgres/create-instance.
Create database - https://cloud.google.com/sql/docs/postgres/create-manage-databases.
Make sure you set it to allow connections from the host you are running your Play server on.
I recommend using the public IP configuration option as it is simpler.
The rest assumes that you have done your development on Pandoras or your personal machine, that you have the SQL commands you used to build your database, and that you have done the CodeGen on your machine.
SSH to your VM and connect to the database.
You need to install the PostgreSQL Client software.
sudo apt-get update
sudo apt-get install postgresql-client
Once you have it installed, you can connect with psql.
psql -h database-public-ip -U database-user -d database-name
You'll have to enter the password you set in the database creation.
Enter the SQL commands to set up your database in the cloud.
Delete your old version and upload your new distribution ZIP file to the cloud. You will make the same changes to conf/application.conf as before. You will also need to update the DB URL. It should look like the following, where you replace each field I've started with "database" with the proper value for your setup.
db.url = "jdbc:postgresql://database-public-ip/database-name?user=database-user&password=database-password"
Task #10 (100 points)
The purpose of this is to get you to do something with Scala.js similar to something you have done before so you can see the differences and similarities.
Repeat task #4 with Scala.js. You can't use a paint program for this.
Task #11 (200 points)
This task brings several things together here at the end of the semester.
Write a page using Play and Scala.js that gives people on the page a shared drawing palette. When you connect, you should start by seeing whatever has already been drawn. You get 150 points for being able to draw anything. You can get an extra 50 points if you make it more powerful with different colors and drawing options (lines, rectangles, circles).
I don't specify how you do this, but most people do it with WebSockets and Canvas. Instead of a Canvas, you can use SVG in Slinky. This approach has some cool advantages but might require more learning and thinking than you feel like doing during the semester. Don't use a database for the drawing. Keep the drawing in memory. I also recommend vector-based graphics and not raster-based graphics.