Merge pull request #38 from ThomasRubini/user_prompts

This commit is contained in:
Thomas Rubini 2022-12-15 19:45:13 +01:00 committed by GitHub
commit fd22eff6cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 320 additions and 16 deletions

View File

@ -11,6 +11,7 @@ public class ArgParse {
/* distribution the user want */
private static String distribution;
private static String packet;
/**
* Get the command line argument given by the user, parse it with the parser and store it in the corresponding variable
@ -27,11 +28,21 @@ public class ArgParse {
try {
// parse the argument from list of String
jCommander.parse(args);
// store the argument parsed in the variable
distribution = params.distribution;
if(params.help) {
jCommander.setProgramName("PackageViewer");
jCommander.usage();
System.exit(0);
} else {
// store the argument parsed in the variable
packet = params.packet;
distribution = params.distribution;
}
} catch (Exception e) {
// if the parsing failed, print the error message and exit the program
System.out.println("You forgot the distribution name.");
System.out.println("You forgot something, please enter the package name and the distribution name if you want to search in a specific one");
jCommander.setProgramName("PackageViewer");
jCommander.usage();
System.exit(0);
}
}
@ -44,4 +55,13 @@ public class ArgParse {
public static String getDistribution() {
return distribution;
}
/**
* Get the packet name, this one isn't optional
* @author Capelier-Marla
* @return String: the packet name
*/
public static String getPacket() {
return packet;
}
}

View File

@ -1,8 +1,5 @@
package fr.packageviewer;
import java.util.ArrayList;
import java.util.List;
import com.beust.jcommander.Parameter;
/**
@ -10,11 +7,13 @@ import com.beust.jcommander.Parameter;
* @author Capelier-Marla
*/
public class CommandLineParams {
/**
* List of parameters given by the user
* Packet the user want to search, only parameter without names
*/
@Parameter
public List<String> parameters = new ArrayList<>();
@Parameter(description = "Package to search",
required = true)
public String packet;
/**
* Distribution the user want to search packages in
@ -23,4 +22,13 @@ public class CommandLineParams {
description = "Linux distribution to search in",
required = false)
public String distribution;
/**
* Displays the help
*/
@Parameter(names = {"--help", "-h"},
description = "Display this help",
help = true,
required = false)
public boolean help = false;
}

View File

@ -0,0 +1,63 @@
package fr.packageviewer;
import java.util.ArrayList;
import java.util.List;
import fr.packageviewer.distribution.ArchDistribution;
import fr.packageviewer.distribution.Distribution;
import fr.packageviewer.distribution.FedoraDistribution;
/**
* Enum containing contructors for each distribution to get them by their name
* @author Capelier-Marla
*/
public enum DistributionEnum {
ARCH("arch", new ArchDistribution()),
FEDORA("fedora", new FedoraDistribution()),
;
private String name;
private Distribution distributionConstructor;
/**
* Contructor for enums
* @param name
* @param distributionConstructor
* @author Capelier-Marla
*/
DistributionEnum(String name, Distribution distributionConstructor) {
this.name = name;
this.distributionConstructor = distributionConstructor;
}
/**
* Get the distribution instance for the distribution requested in String
* @param name name of the distribution requested
* @return the instance of the distribution requested
* @author Capelier-Marla
*/
public static Distribution getDistributionContructorByName(String name) {
// loop for all ditributions stored in enum
for(var distrib : values()) {
// return the instance if it's the same as enum name
if(distrib.name.equals(name)) {
return distrib.distributionConstructor;
}
}
return null;
}
/**
* Get all distribution instances available in this enum
* @return the set of distribution instances
*/
public static List<Distribution> getAllDistributionsInstances() {
// create the set that will be returned
List<Distribution> result = new ArrayList<>();
// add all the distribution instances in the set
for(var ditrib : values()) {
result.add(ditrib.distributionConstructor);
}
return result;
}
}

View File

@ -1,10 +1,36 @@
package fr.packageviewer;
public class Main {
import java.util.List;
import fr.packageviewer.frontend.Frontend;
import fr.packageviewer.frontend.FrontendFactory;
import fr.packageviewer.pack.Package;
import fr.packageviewer.pack.SearchedPackage;
public class Main {
public static void main(String[] args) {
// create the frontend : what the user will see in its terminal
Frontend frontend = FrontendFactory.get("terminal");
// send the command line arguments to the parser
ArgParse.parseArguments(args);
System.out.println(ArgParse.getDistribution());
String packetName = ArgParse.getPacket();
String distribution = ArgParse.getDistribution();
// we create an object to search the packages in the distribution
Searcher searcher = new Searcher(distribution);
// we get the packages list
List<SearchedPackage> packets = searcher.searchPackages(packetName);
// ask the user to select the package to see in details and store its name
SearchedPackage searchedPacketName = frontend.askUserToChoosePackage(packets);
// get all informations about the package by searching it in details
Package packet = searcher.getPackage(searchedPacketName);
// show all informations about a packet
frontend.showPackageTree(packet, 0);
}
}

View File

@ -0,0 +1,78 @@
package fr.packageviewer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import fr.packageviewer.distribution.Distribution;
import fr.packageviewer.pack.SearchedPackage;
import fr.packageviewer.pack.Package;
public class Searcher {
private String distributionName = null;
public Searcher(String distributionName) {
this.distributionName = distributionName;
}
/**
* Get the list of all packages in the distribution setted before
* @param packageName the name of the package wanted
* @return the list of all packages found
* @author Capelier-Marla
*/
public List<SearchedPackage> searchPackages(String packageName) {
// we add all instanced constructors in a list, only one if defined at creation of the object
List<Distribution> distributions;
if(distributionName == null) {
distributions = DistributionEnum.getAllDistributionsInstances();
} else {
distributions = Collections.singletonList(DistributionEnum.getDistributionContructorByName(distributionName));
if(distributions.get(0) == null) {
System.out.println("Distribution non trouvée");
System.exit(0);
}
}
// this is the list we will return containing all packages
List<SearchedPackage> allPackages = new ArrayList<>();
// this contains all future list of packages to get them after
List<Future<List<SearchedPackage>>> listFuturePackagesList = new ArrayList<>();
// we add all future packages in a list
for (Distribution distribution : distributions) {
listFuturePackagesList.add(distribution.searchPackage(packageName));
}
// we get all packages waiting for them to be received
for(Future<List<SearchedPackage>> futurePackageList : listFuturePackagesList ) {
try {
List<SearchedPackage> tempList = futurePackageList.get();
allPackages.addAll(tempList);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
return allPackages;
}
public Package getPackage(SearchedPackage packetInput) {
if(distributionName == null) {
distributionName = packetInput.getDistribution();
}
String packageName = packetInput.getName();
Distribution distribution = DistributionEnum.getDistributionContructorByName(distributionName);
Future<Package> futurePacket = distribution.getPackageTree(packageName, 4);
Package packet = null;
try {
packet = futurePacket.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return packet;
}
}

View File

@ -17,7 +17,7 @@ import fr.packageviewer.LoggerManager;
/**
* This class handles package requests for Fedora. All return objects in
* this class are wrapped by a CompletableFuture to ensure async workload.
*
*
* @author S.Djalim, R.Thomas
* @version 1.0
*/
@ -32,7 +32,7 @@ public class FedoraDistribution extends AsyncRequestsParser implements Distribut
* This function return a package from Fedora metadata api in the form of a
* Pair Composed of a Package object, and a set of string containing the
* names of the dependecies of the package.
*
*
* @param packageName String, The package's exact name
* @return Pair of Package and Set of String
*/
@ -75,7 +75,7 @@ public class FedoraDistribution extends AsyncRequestsParser implements Distribut
json.getString("basename"),
json.getString("version"),
"rawhide",
json.getString("description"),
json.getString("summary"),
"fedora"
),
dependenciesNames
@ -93,7 +93,7 @@ public class FedoraDistribution extends AsyncRequestsParser implements Distribut
/**
* Search for a package matching a pattern and return a list of packages and
* return a list of string matching this pattern.
*
*
* @param packageName String, the pattern to search in the repositories
* @return List of SearchedPackage objects
*/
@ -111,7 +111,7 @@ public class FedoraDistribution extends AsyncRequestsParser implements Distribut
// send the request and when there's a response
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept(result -> {
//parse the json response
//parse the json response
JSONObject json = new JSONObject(result.body());
List<SearchedPackage> searchedPackagesList = new ArrayList<>();

View File

@ -0,0 +1,11 @@
package fr.packageviewer.frontend;
import java.util.List;
import fr.packageviewer.pack.Package;
import fr.packageviewer.pack.SearchedPackage;
public interface Frontend {
SearchedPackage askUserToChoosePackage(List<SearchedPackage> packets);
void showPackageTree(Package packet, int depth);
}

View File

@ -0,0 +1,16 @@
package fr.packageviewer.frontend;
public class FrontendFactory {
public static Frontend get(String name){
switch(name){
case "terminal":{
return new FrontendTerminal();
}
default:{
throw new IllegalArgumentException("Invalid frontend");
}
}
}
}

View File

@ -0,0 +1,82 @@
package fr.packageviewer.frontend;
import java.util.List;
import java.util.Scanner;
import fr.packageviewer.pack.Package;
import fr.packageviewer.pack.SearchedPackage;
public class FrontendTerminal implements Frontend{
/**
* Check if the String given is a number
* @param i the String given
* @return true if the String is a number
* @author Capelier-Marla
*/
private static boolean isNumeric(String i) {
try {
Integer.parseInt(i);
return true;
} catch (Exception e) {
return false;
}
}
@Override
public SearchedPackage askUserToChoosePackage(List<SearchedPackage> packets) {
// list all packages in reverse order
for (int i = packets.size(); i-- > 0; ) {
SearchedPackage searchedPacket = packets.get(i);
System.out.printf("%s - %s/%s/%s %s%n\t%s%n",
i,
searchedPacket.getDistribution(),
searchedPacket.getRepo(),
searchedPacket.getName(),
searchedPacket.getVersion()==null?"":searchedPacket.getVersion(),
searchedPacket.getDescription());
}
System.out.printf("Pick a package to see in details (0-%s) : ", packets.size()-1);
Scanner input = new Scanner(System.in);
// we create vars for the loop
String packetNumberString;
int packetNumber = -1;
boolean notValid;
// we ask input and check if the user input is correct
do {
packetNumberString = input.nextLine();
// reset notValid to false, we set it in true only if something is wrong
notValid = false;
if(isNumeric(packetNumberString)) {
packetNumber = Integer.parseInt(packetNumberString);
if(packetNumber < 0 || packetNumber >= packets.size()) {
// this number is too big or too small
System.out.println("Enter a valid number");
notValid = true;
}
} else {
// this is not a number
System.out.println("Enter a valid number");
notValid = true;
}
} while(notValid);
input.close();
return packets.get(packetNumber);
}
@Override
public void showPackageTree(Package packet, int depth) {
System.out.printf("%s%s / %s : %s%n",
" ".repeat(depth),
packet.getName(),
packet.getVersion(),
packet.getDescription());
for (Package dep : packet.getDeps()) {
showPackageTree(dep, depth+1);
}
}
}