Create Template
Introduction
Before beginning, you will need to setup the program to authenticate with Google.
This is mostly setup for you, however you will need to update the clientID, clientSecret, and CALLBACK_URI variables to fit your needs.
The clientID and clientSecret variables are for you to insert your Google OAuth Client ID and secret into.
At time of writing, these were in Google Cloud Platform, but please double check current documentation to ensure accuracy.
Finally, once you have set these, you will be able to connect to Google's servers. When complete Google will try to return control back to your application.
The CALLBACK_URI variable is the link you want Google to take the user to when control is returned. Examples of this could include
http://localhost:8080/callback or https://website.com/callback . Please note that Google supports multiple callback URIs which will
allow both the createTemplate and analyzeData classes to have different URIs to distinguish their origin/purpose. Within the createTemplate version of this variable,
insert the callback URI for the creation of the template. In the source code, this is the /templateoauth page of your website (again, this could be localhost or another website).
Failing to enter this correctly will result in errors while running the code.
createTemplate()
Please note this code is based on that of Matyas Danter. Direct links to his code will be provided in the References section.
This acts as the constructor for the createTemplate class. It begins the process of creating an OAuth login screen for the user by use of the GoogleAuthorizationCodeFlow.Builder() function.
It requires an HTTP Transport, JSON Factory, Google OAuth Client ID and secret, as well as a defined access scope.
Additionally, the type of access can be set to determine whether or not access should be permitted when the user is not present at the browser.
Additional details can be found in Reference 1 in the Additional Reading Section.
The HTTP_TRANSPORT, JSON_FACTORY, and SCOPES variables are all part of a class definition (as well as the ClientID and clientSecret mentioned in the Introduction section).
The only one of these that should need any editing is the SCOPES variable.
SCOPES allows you to choose what type of data access the service requires. In the case of Nebula, the ability to read and write from our user's file repository (Google Drive via Google Sheets)
so this is set to SheetsScopes.SPREADSHEETS per Google's documentation (this is Reference 2 in the Additional Reading Section).
buildLoginURL()
This function simply creates a new Google OAuth URL such that users can securely login to their Google accounts to access Nebula.
This is done using a randomly generated state token.
builder() & builderWithCredentials()
These two functions are exactly the same with the only difference being the credential variable is set to the credential variable defined in the class.
They are designed to continue the authentication flow (see Additional Reading Link 1 for more details) and creates a service object for the Google Sheets API.
The builderWithCredentials() function is used only when a function is used in both the createTemplate and analyzeData classes which
each require their own credentials to work as they each have a different callback URI.
createSpreadsheet()
This function requires the authorization code for OAuth (the returned code from the Google callback) as well as the desired title for the spreadsheet
(this is also the assignment name in other functions), as well as the number of students taking the assignment and the number of questions on the assignment.
The code begins by converting the authorization code (authCode) into a token credential. The finalized credential is stored in the credential variable for the class.
Then the builder function creates the service object used to create various authenticated requests. This function will make only one of these requests
to create a new spreadsheet (please note this is different from a worksheet - a spreadsheet is the Google Sheets equivalent of an Excel workbook and can contain many worksheets).
To do this, a new variable of type Spreadsheet will be created and the title property of the spreadsheet will be set to the provided title/assignment name.
Next, that variable will be used to create a new spreadsheet.
Additional information regarding these API calls can be found in the Google documentation available at the fourth link in the Additional Reading section.
Next, the spreadsheet ID will be obtained from the spreadsheet variable.
After this, the dashboard function will be called which will fill in the first worksheet of the newly created spreadsheet.
Additional detail will be provided in the dashboard() section of this page.
Subsequently, a new worksheet within the spreadsheet will be created and formatted out for the user to enter their students' grades and answer key into using the
newWorksheet() and formatStudentData() functions respectively.
Finally, the spreadsheet ID is returned to the calling function.
dashboard()
This function creates a welcome page for the user when they open the spreadsheet. It gives them easy access to the link that begins analysis of the entered student data.
The changeSheetTitle() function is used to change the name of the current worksheet to Dashboard.
The headingCells() function merges cells together to make a single heading cell with bold text.
The mergeCells() function allows multiple cells in a given row or column to be merged together.
Additionally, text has been provided to populate all merges cells. This is inserted into the cells using the bulkAddText()
function which appends a text adding request to a predefined ArrayList object (in the case of Nebula, one named requests).
A formula is then created to add to a button to create a link. The newButton() function creates the requests to merge the cells,
color them, and put a formula in them which will generate a functional button.
Finally, all of the requests are processed at once which helps reduce calls to the server and speeds up the code.
Additional information on all functions mentioned in this section is available in their respective sections in this document.
changeSheetTitle()
This function creates and executes a request to change the worksheet title to an updated title passed into the function.
This function follows the Google Sheets API v4 request pattern. Additional information about the mechanics of the API and
by extension this function can be found in the 4th link of the Additional Reading section of this documentation.
headingCells()
This function begins by merging the cells the heading text will be placed into. Then an ArrayList object is created which will
contain the request to set the title and the range of the new heading cell as well as any formatting.
Finally, the request is executed.
Additional information on types of formatting can be found at Link 4 in the Additional Reading section of this documentation.
mergeCells()
This function performs a MergeCellsRequest() as documented in the Google Sheets API (additional information can be found in the 4th link of the Additional Reading section of this documentation).
bulkAddText()
This function adds requests to an ArrayList. Specifically, in each request the Range, data, and formatting of a cell is set as documented in the Google Sheets API
(additional information can be found in the 4th link of the Additional Reading section of this documentation).
newButton()
This function begins by making an initial call to mergeCells() to ensure the button is sufficient size.
Next, a request is generated and added to a passed in ArrayList. The request will set the range of cells to execute the request on,
the text and cell format of the cell, as well as its data. The cell and text colors are done in the RGB color format. Please note all RGB values are entered as floating point numbers.
For example, if you wanted the background of the cell to be pure red, the RGB values would be 255,0,0 so backgroundRed would be 1f, and backgroundGreen
and backgroundBlue would be set to zero. If you are new to RGB, please use the 5th link on the Additional Reading page to get you started.
newWorksheet()
This function requires the spreadsheet ID, title for the new worksheet (this will appear on the worksheet's tab at the bottom of the screen),
and the index which refers to the position of the worksheet in the spreadsheet. For example, if there is only one worksheet in your spreadsheet and you wish to add a second,
you would set index to 1. This is the exact scenario used in the createSpreadsheet() to call this function.
formatStudentData()
This function begins by creating headings using the headingCells() function and by appending the number of questions on the assignment to the worksheet.
This allows for there to be a column for each question and prevent running out of room.
After this, bulkCenteredCells() is called in repeatedly to create requests that will create the labels for each piece of data to enter.
For example, one set of requests creates Question 1, Question 2, etc going down in a column on the left side to signify which cell
(in this case the one immediately to the right) to put the answer for that question in. This will create the area for the user to enter the assignment answer key.
bulkCenteredCells()
This function first checks to see if the cells are to be placed with one cell in each column (this is when the inColumns variable would be true)
or with all cells in one column (this would be when inColumns is false). After this, requests are created and added to an ArrayList passed in from another function.
Each request will set the range, font size, and text alignment of the cell(s).
appendColumns()
This function takes in the spreadsheet ID and the number of columns that need to be added. By default, Nebula adds the same number of columns as there are question numbers to the
Student Grades worksheet to ensure sufficient space for all questions to have their own columns. A request will be created and executed to append the size of the worksheet
in a given dimension (only one dimension can be changed at a time).
spreadsheetURL()
This function takes in the spreadsheet ID (this is generated by Google - more information is available in their getting started document for the Google Sheets API which is available at Link 3
in the Additional Reading section) and generates a direct link to the spreadsheet.