Skip to content

Commit

Permalink
Merge pull request #155 from ucsd-cse110-fa23/Feature-10
Browse files Browse the repository at this point in the history
User Story 10 (Issues #152, 153, 154, 156, 157): Automatic Login
  • Loading branch information
hashreds authored Dec 6, 2023
2 parents 9592e63 + 2d798eb commit b7924c6
Show file tree
Hide file tree
Showing 18 changed files with 972 additions and 739 deletions.
22 changes: 15 additions & 7 deletions app/src/main/java/cse/gradle/App.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package cse.gradle;

import java.util.ArrayList;

import java.util.List;
import java.io.*;
import javafx.application.Application;
import javafx.stage.Stage;

Expand All @@ -17,20 +18,27 @@ public void start(Stage primaryStage) throws Exception {
// initialize relevant classes
ArrayList<Recipe> arrayList = new ArrayList<Recipe>();

try {
// TODO: Move this code to run after the user logs in
// ArrayList<Recipe> rList = (ArrayList<Recipe>)objectMapper.readValue(response, new TypeReference<List<Recipe>>() {});
// arrayList = new ArrayList<Recipe>(rList);
} catch (Exception e) {
System.out.println("Error reading JSON from server on startup");
}

// Create a Model object
Model model = new Model("http://localhost:8100");

// Create a controller object to mediate between the view and the model
Controller controller = new Controller(model);
// Create a View object to handle the UI and pass it the controller for button listeners
View appScenes = new View(primaryStage, arrayList);

// Create a View object to handle the UI and pass it the controller for button
// listeners
View appScenes = new View(primaryStage, arrayList, controller);
// Create a controller object to mediate between the view and the model
Controller controller = new Controller(model, appScenes);

// Set the title of the app
primaryStage.setTitle("PantryPal");
// Create scene of mentioned size with the border pane
primaryStage.setScene(appScenes.getScene());
primaryStage.setScene(appScenes.getLoginScene());
// Make window non-resizable
primaryStage.setResizable(true);
// Show the app
Expand Down
111 changes: 91 additions & 20 deletions app/src/main/java/cse/gradle/Controller.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
package cse.gradle;

import java.util.List;

import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.io.*;

import cse.gradle.View.AppFramePopUp;
import cse.gradle.View.NewRecipePane;
import cse.gradle.View.RecipeList;
import cse.gradle.View.UserCreateAccount;
import cse.gradle.View.UserLogin;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.stage.Stage;

public class Controller {
public class Controller implements ModelObserver, ViewObserver {

private Model model;
private View view;

public Controller(Model model) {
public Controller(Model model, View view) {
this.model = model;
this.view = view;
model.register(this);
view.register(this);
}

public void createUser(String username, String password, View appScenes) {
Expand All @@ -22,14 +35,51 @@ public void createUser(String username, String password, View appScenes) {
}
}

public boolean loginUser(String username, String password, View appScenes) {
public boolean loginUser(String username, String password, View appScenes, UserLogin loginPage) throws IOException {
// Checks if the automic login file exists; if it does, and username matches the
// one in file, do automatic login
if ((new File("src/main/java/cse/gradle/local/login.txt")).exists()) {
File loginFile = new File("src/main/java/cse/gradle/local/login.txt");
BufferedReader reader = new BufferedReader(
new FileReader(loginFile));
if (username.equals(reader.readLine())) {
reader.close();
String postResponse = model.performLoginRequest(loginFile);
if (postResponse.equals("Error: Server down")) {
appScenes.displayServerDownConstructor();
return false;
}
reader.close();
return true;
}
reader.close();
return loginUserWithButtonCheck(username, password, appScenes, loginPage);
} else {
return loginUserWithButtonCheck(username, password, appScenes, loginPage);
}
}

// Logs-in the user and writes to login.txt file if the automatic login checkbox
// is selected
public boolean loginUserWithButtonCheck(String username, String password, View appScenes, UserLogin loginPage) {
String postResponse = model.performLoginRequest(username, password);
if ((loginPage.getAutoLoginButton().isSelected()) && (!postResponse.contains("Invalid"))) {
try {
FileWriter writer = new FileWriter("src/main/java/cse/gradle/local/login.txt");
writer.write(username + "\n" + password);
writer.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (postResponse.equals("Error: Server down")) {
appScenes.displayServerDownConstructor();
return false;
} else if (postResponse.contains("Incorrect password")) {
appScenes.displayIncorrectPassword();
return false;
} else if (postResponse.contains("does not exist")) {
return false;
}
return true;
}
Expand Down Expand Up @@ -111,7 +161,7 @@ public void deleteRecipe(AppFramePopUp popUp, View appScenes, Recipe recipe, Rec
}

// Sets the listensers for all the buttons within the recipe creation window
void setListeners(NewRecipePane recipePane, View appScenes, Scene cancelScene) {
public void setRecipeCreationListeners(NewRecipePane recipePane, View appScenes, Scene cancelScene) {

recipePane.getRecordMealTypeButton().setOnAction(e -> {
if (!recipePane.getRecordingInProgress()) {
Expand Down Expand Up @@ -173,7 +223,7 @@ void setListeners(NewRecipePane recipePane, View appScenes, Scene cancelScene) {
}

// Sets the listensers for all the buttons within the account creation window
void setListeners(UserCreateAccount createPane, View appScenes) {
public void setAccountWindowListeners(UserCreateAccount createPane, View appScenes) {

createPane.getCreateButton().setOnAction(e -> {
String username = createPane.getUsernameField().getText().toString();
Expand All @@ -192,31 +242,52 @@ void setListeners(UserCreateAccount createPane, View appScenes) {
}

// Sets the listensers for all the buttons within the account login window
void setListeners(UserLogin userPane, View appScenes) {
public void setLoginWindowListeners(UserLogin loginPage, View appScenes) {

userPane.getCreateButton().setOnAction(e -> {
loginPage.getCreateButton().setOnAction(e -> {
appScenes.displayUserAccountSceneConstructor();
});

// When the login button is pressed, make a request to the server to login the
// user, then make a get all recipes request and display the recipe list scene
userPane.getLoginButton().setOnAction(e -> {
String username = userPane.getUsernameField().getText().toString();
String password = userPane.getPasswordField().getText().toString();
boolean loginResult = loginUser(username, password, appScenes);

// Get all recipes from the database and display
// When logging into account, start with default sorted list
if (loginResult) {
syncRecipeListWithModel(appScenes, Constants.defaultSortOption, Constants.defaultMealType);
// When the login button is pressed, make a request to the server to login the user
// then make a get all recipes request and display the recipe list scene
loginPage.getLoginButton().setOnAction(e -> {
String username = loginPage.getUsernameField().getText().toString();
String password = loginPage.getPasswordField().getText().toString();
boolean loginResult;
try {
loginResult = loginUser(username, password, appScenes, loginPage);
// Get all recipes from the database and display
// When logging into account, start with default sorted list
if (loginResult) {
syncRecipeListWithModel(appScenes, Constants.defaultSortOption, Constants.defaultMealType);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
});
}

void setListeners(RecipeList recipeList, View appScenes) {
// Sets the listensers for all buttons within the AppFramePopUp window
public void setRecipePopUpListeners(AppFramePopUp recipePopUp, RecipeList recipeList, Recipe recipe) {

recipePopUp.getSaveButton().setOnAction(e -> {
this.saveRecipe(recipePopUp, recipeList.appScenes, recipe, recipeList);
});

recipePopUp.getDeleteButton().setOnAction(e -> {
this.deleteRecipe(recipePopUp, recipeList.appScenes, recipe, recipeList);
});
recipePopUp.getShareButton().setOnAction(e -> {
this.shareRecipe(recipe);
});
}

public void setRecipeListListeners(RecipeList recipeList, View appScenes) {
// button
recipeList.getNewRecipeButton().setOnAction(e -> {
appScenes.displayNewRecipeScene();
System.out.println("New Recipe pressed");
});

recipeList.getLogoutButton().setOnAction(e -> {
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/cse/gradle/DisplayRecipe.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package cse.gradle;

import cse.gradle.View.AppFramePopUp;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.stage.Stage;

Expand Down
14 changes: 14 additions & 0 deletions app/src/main/java/cse/gradle/MockRecipeList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package cse.gradle;

import java.util.List;

import cse.gradle.View.RecipeList;

public class MockRecipeList extends RecipeList {

public MockRecipeList(View view, List<Recipe> list) {
view.super(list);
//TODO Auto-generated constructor stub
}

}
15 changes: 15 additions & 0 deletions app/src/main/java/cse/gradle/MockView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cse.gradle;

import java.util.List;

import cse.gradle.View.RecipeList;

public class MockView extends View {
public MockView(List<Recipe> rList) {
super(rList);
}

public List<Recipe> getRecipeList() {
return this.getListOfRecipes();
}
}
31 changes: 30 additions & 1 deletion app/src/main/java/cse/gradle/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,15 @@
import java.net.URI;
import java.net.URISyntaxException;

public class Model {
import java.io.*;
import java.net.*;
import java.util.*;
import org.json.*;

public class Model implements ModelSubject {
protected String userId;
protected String urlString;
protected ArrayList<ModelObserver> obsList = new ArrayList<ModelObserver>();

public Model(String urlString) {
this.userId = null;
Expand Down Expand Up @@ -199,6 +205,24 @@ public String performLoginRequest(String username, String password) {
}
}

// Overloaded method for automatic login
public String performLoginRequest(File loginFile) {
try {
BufferedReader reader = new BufferedReader(
new FileReader(loginFile));
String username = reader.readLine();
String password = reader.readLine();
//System.out.println("\n" + username + "\n");

reader.close();

return performLoginRequest(username, password);
} catch (IOException e) {
e.printStackTrace();
return "Error: " + e.getMessage();
}
}

// make a request to register a new user
public String performRegisterRequest(String username, String password) {
try {
Expand Down Expand Up @@ -272,6 +296,11 @@ public static String[] performRecipeGenerationRequest(String mealType, String in
return response;
}

@Override
public void register(ModelObserver obs) {
obsList.add(obs);
}

public String performFileWriteRequest(String audioFile) throws MalformedURLException, IOException {
final String PUT_URL = "http://localhost:8100/generate?audioFile=" + audioFile;
final File uploadFile = new File(audioFile);
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/cse/gradle/ModelObserver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package cse.gradle;

public interface ModelObserver {

}
5 changes: 5 additions & 0 deletions app/src/main/java/cse/gradle/ModelSubject.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package cse.gradle;

public interface ModelSubject {
public void register(ModelObserver obs);
}
Loading

0 comments on commit b7924c6

Please sign in to comment.