diff --git a/BreakingNews/src/main/java/AP/Infrastructure.java b/BreakingNews/src/main/java/AP/Infrastructure.java index 84d4e6f..c15e950 100644 --- a/BreakingNews/src/main/java/AP/Infrastructure.java +++ b/BreakingNews/src/main/java/AP/Infrastructure.java @@ -1,60 +1,105 @@ -package AP; - -import java.io.IOException; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.util.ArrayList; - -public class Infrastructure { - - private final String URL; - private final String APIKEY; - private final String JSONRESULT; - private ArrayList newsList; // TODO: Create the News class - - - public Infrastructure(String APIKEY) { - this.APIKEY = APIKEY; - this.URL = "https://newsapi.org/v2/everything?q=tesla&from=2025-02-05&sortBy=publishedAt&apiKey="; - this.JSONRESULT = getInformation(); - } - - public ArrayList getNewsList() { - return newsList; - } - - private String getInformation() { - try { - HttpClient client = HttpClient.newHttpClient(); - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(URL + APIKEY)) - .build(); - - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - if (response.statusCode() == 200) { - return response.body(); - } else { - throw new IOException("HTTP error code: " + response.statusCode()); + package AP; + + import java.io.IOException; + import java.net.URI; + import java.net.http.HttpClient; + import java.net.http.HttpRequest; + import java.net.http.HttpResponse; + import java.util.ArrayList; + import java.time.LocalDate; + import java.util.Scanner; + import org.json.JSONArray; + import org.json.JSONObject; + + public class Infrastructure { + + private final String URL; + private final String APIKEY; + private final String JSONRESULT; + private ArrayList newsList; + + public Infrastructure(String APIKEY) { + this.APIKEY = APIKEY; + this.URL = "https://newsapi.org/v2/everything?q=tesla&from=" + + LocalDate.now().minusDays(1) + "&sortBy=publishedAt&apiKey="; + this.JSONRESULT = getInformation(); + parseInformation(); // Ensure newsList is populated + } + + public ArrayList getNewsList() { + return newsList; + } + + private String getInformation() { + try { + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(URL + APIKEY)) + .build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + if (response.statusCode() == 200) { + return response.body(); + } else { + throw new IOException("HTTP error code: " + response.statusCode()); + } + } catch (Exception e) { + System.out.println("Exception: " + e.getMessage()); + } + return null; + } + + private void parseInformation() { + if (JSONRESULT == null || JSONRESULT.isEmpty()) { + System.out.println("No data received from API."); + return; + } + + newsList = new ArrayList<>(); + + try { + JSONObject jsonResponse = new JSONObject(JSONRESULT); + JSONArray articles = jsonResponse.getJSONArray("articles"); + + for (int i = 0; i < Math.min(20, articles.length()); i++) { + JSONObject article = articles.getJSONObject(i); + + String title = article.optString("title", "No Title"); + String description = article.optString("description", "No Description"); + String sourceName = article.has("source") ? article.getJSONObject("source").optString("name", "Unknown Source") : "Unknown Source"; + String author = article.optString("author", "Unknown"); + String url = article.optString("url", "No URL"); + String publishedAt = article.optString("publishedAt", "Unknown Date"); + + newsList.add(new News(title, description, sourceName, author, url, publishedAt)); + } + } catch (Exception e) { + System.out.println("Error parsing JSON: " + e.getMessage()); + } + } + + public void displayNewsList() { + if (newsList == null || newsList.isEmpty()) { + System.out.println("No news available."); + return; + } + + for (int i = 0; i < newsList.size(); i++) { + System.out.println((i + 1) + ". " + newsList.get(i).getTitle()); + } + + Scanner scanner = new Scanner(System.in); + System.out.println("\nEnter the number of the article you want to read, or 0 to exit:"); + + int choice = scanner.nextInt(); + + if (choice > 0 && choice <= newsList.size()) { + newsList.get(choice - 1).displayNews(); + } else if (choice == 0) { + System.out.println("Exiting..."); + } else { + System.out.println("Invalid choice. Please enter a valid number."); + } + scanner.close(); + } } - } catch (Exception e) { - System.out.println("!!Exception : " + e.getMessage()); - } - return null; - } - - private void parseInformation() { - // TODO: Get the first 20 news from the articles array of the json result - // and parse the information of each on of them to be mapped to News class - // finally add them to newsList in this class to display them in the output - } - - public void displayNewsList() { - // TODO: Display titles of the news you got from api - // and print them in a way that user can choose one - // to see the full information of the news - } - -} diff --git a/BreakingNews/src/main/java/AP/Main.java b/BreakingNews/src/main/java/AP/Main.java index ae51d7d..bd2ef73 100644 --- a/BreakingNews/src/main/java/AP/Main.java +++ b/BreakingNews/src/main/java/AP/Main.java @@ -1,7 +1,55 @@ -package AP; +import java.util.Scanner; public class Main { + public static void main(String[] args) { + String apiKey = "dc75747245e245b591be58873847bd6e"; + + Infrastructure infrastructure = new Infrastructure(apiKey); + + infrastructure.parseInformation(); + + displayMenu(infrastructure); + } + + private static void displayMenu(Infrastructure infrastructure) { + if (infrastructure.getNewsList() == null || infrastructure.getNewsList().isEmpty()) { + System.out.println("No news available. Please check if the API key is correct or if there was an issue with the API."); + return; + } + + Scanner scanner = new Scanner(System.in); + + while (true) { + System.out.println("\n--- News Menu ---"); + for (int i = 0; i < infrastructure.getNewsList().size(); i++) { + News news = infrastructure.getNewsList().get(i); + System.out.println((i + 1) + ". " + news.getTitle()); + } + + System.out.println("\nEnter the number of the article you want to read, or 0 to exit:"); + + try { + int choice = scanner.nextInt(); + + if (choice == 0) { + System.out.println("Exiting..."); + break; + } + + if (choice > 0 && choice <= infrastructure.getNewsList().size()) { + News selectedNews = infrastructure.getNewsList().get(choice - 1); + selectedNews.displayNews(); + } else { + System.out.println("Invalid choice. Please enter a valid number."); + } + + } catch (Exception e) { + System.out.println("Error: Invalid input. Please enter a valid number."); + scanner.nextLine(); + } + } + scanner.close(); } -} \ No newline at end of file +} diff --git a/BreakingNews/src/main/java/AP/News.java b/BreakingNews/src/main/java/AP/News.java new file mode 100644 index 0000000..c52b348 --- /dev/null +++ b/BreakingNews/src/main/java/AP/News.java @@ -0,0 +1,53 @@ +public class News { + private String title; + private String description; + private String sourceName; + private String author; + private String url; + private String publishedAt; + + public News(String title, String description, String sourceName, String author, String url, String publishedAt) { + this.title = title; + this.description = description; + this.sourceName = sourceName; + this.author = author; + this.url = url; + this.publishedAt = publishedAt; + } + + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + public String getSourceName() { + return sourceName; + } + + public String getAuthor() { + return author; + } + + public String getUrl() { + return url; + } + + public String getPublishedAt() { + return publishedAt; + } + + public void displayNews() { + System.out.println("\nšŸ“° NEWS ARTICLE"); + System.out.println("šŸ“Œ Title: " + title); + System.out.println("šŸ“ Description: " + (description != null && !description.isEmpty() ? description : "No Description Available")); + System.out.println("šŸ›ļø Source: " + sourceName); + System.out.println("āœļø Author: " + (author != null && !author.isEmpty() ? author : "Unknown")); + System.out.println("šŸ“… Published At: " + publishedAt); + System.out.println("šŸ”— Read More: " + url); + System.out.println("-----------------------------------------"); + } +} diff --git a/Report.md b/Report.md index d437803..b0763b3 100644 --- a/Report.md +++ b/Report.md @@ -1,62 +1,60 @@ # Project Title +News Aggregator -Simple overview of use/purpose. +## Overview +This project is a Java-based news aggregator that fetches and displays the latest news articles related to "Tesla" using the NewsAPI. It integrates API calls, JSON parsing, and user interaction through a menu-driven console interface. ## Description - -An in-depth paragraph about your project and overview of use. +The News Aggregator is designed to fetch the latest articles from NewsAPI and present them in a structured format. The program retrieves articles using an HTTP request, parses the JSON response, and stores the relevant information for easy access. Users can browse news headlines, select articles for detailed viewing, and navigate through the news list interactively. ## Getting Started ### Dependencies - -* Describe any prerequisites, libraries, OS version, etc., needed before installing program. -* ex. Windows 10 +Before running the program, ensure you have the following prerequisites: +- Java Development Kit (JDK) 11 or later +- Internet connection for API requests +- NewsAPI API key ### Installing - -* How/where to download your program -* Any modifications needed to be made to files/folders - -### Executing program - -* How to run the program -* Step-by-step bullets -``` -code blocks for commands -``` +1. Clone the repository: + ```sh + git clone https://github.com/your-repo/news-aggregator.git + ``` +2. Navigate to the project directory: + ```sh + cd news-aggregator + ``` +3. Ensure the `APIKEY` is correctly set in the `Main` class. + +### Executing Program +To run the program, follow these steps: +1. Compile the Java files: + ```sh + javac AP/*.java + ``` +2. Run the main application: + ```sh + java AP.Main + ``` ## Help - -Any advise for common problems or issues. -``` -command to run if program contains helper info -``` +If you encounter issues: +- Ensure your API key is correct and active. +- Verify that your internet connection is stable. +- If an error occurs, check the console output for debugging information. ## Authors - -Contributors names and contact info - -ex. Dominique Pizzie -ex. [@DomPizzie](https://twitter.com/dompizzie) +- **Mohammad Mahdi Aghanejad** - ## Version History - -* 0.2 - * Various bug fixes and optimizations - * See [commit change]() or See [release history]() -* 0.1 - * Initial Release +- **0.2** - Various bug fixes and optimizations (See commit history) +- **0.1** - Initial release ## License - -This project is licensed under the [NAME HERE] License - see the LICENSE.md file for details +This project is licensed under the MIT License - see the `LICENSE.md` file for details. ## Acknowledgments +- NewsAPI for providing the news data. +- Open-source Java communities for guidance. +- Inspiration from similar news aggregation projects. -Inspiration, code snippets, etc. -* [awesome-readme](https://github.com/matiassingers/awesome-readme) -* [PurpleBooth](https://gist.github.com/PurpleBooth/109311bb0361f32d87a2) -* [dbader](https://github.com/dbader/readme-template) -* [zenorocha](https://gist.github.com/zenorocha/4526327) -* [fvcproductions](https://gist.github.com/fvcproductions/1bfc2d4aecb01a834b46)