Merge branch 'main' into ci

This commit is contained in:
Thomas Rubini 2022-12-12 21:53:36 +01:00 committed by GitHub
commit b045e98978
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 227 additions and 147 deletions

View File

@ -8,6 +8,11 @@ version '1.0-SNAPSHOT'
mainClassName = 'fr.packageviewer.Main'
java {
sourceCompatibility = JavaVersion.VERSION_13
targetCompatibility = JavaVersion.VERSION_13
}
jar{
manifest {
attributes(

View File

@ -1,118 +0,0 @@
package fr.packageviewer.ArchParser;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.net.http.*;
import org.json.*;
public class ArchParser {
/**
* Will return the String json of the package from the Arch Linux API
* @param packageName the package name to get the json from
* @return json of the package
*/
public String getPackageFromAPI(String packageName){
// create a new http client
HttpClient client = HttpClient.newHttpClient();
// and create its url
HttpRequest request = HttpRequest.newBuilder(URI.create("https://archlinux.org/packages/search/json/?name="+packageName)).build();
// send its url and return the string given
try {
return client.send(request, HttpResponse.BodyHandlers.ofString()).body();
} catch (IOException|InterruptedException e) {
e.printStackTrace();
}
// if there's an error, return an empty string
return "";
}
/**
* Search for a package and return a list of packages
* @param packageName the package name to search
* @return
*/
public List<SearchedPackage> searchPackage(String packageName){
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://archlinux.org/packages/search/json/?q="+packageName))
.build();
HttpResponse<String> response;
try{
response = client.send(request, HttpResponse.BodyHandlers.ofString());
}catch(IOException|InterruptedException e){
e.printStackTrace();
return null;
}
JSONObject json = new JSONObject(response.body());
List<SearchedPackage> searchedPackagesList = new ArrayList<>();
// iterate for every package in the list
for (Object searchResultObj : json.getJSONArray("results")) {
// convert object into String
JSONObject searchResultJson = (JSONObject) searchResultObj;
// add package into to list
searchedPackagesList.add(new SearchedPackage(
searchResultJson.getString("pkgname"),
searchResultJson.getString("pkgver"),
searchResultJson.getString("repo"),
searchResultJson.getString("pkgdesc")
));
}
return searchedPackagesList;
}
/**
* Will generate a dependencies tree of depth 'depth' given the package name
* @param packageName the package name to search
* @param depth depth to search dependencies
* @return new Package
*/
public Package getPackageTree(String packageName, int depth){
String name, version, repo, description;
List<Package> deps = new ArrayList<>();
// parse the json
JSONObject json = new JSONObject(getPackageFromAPI(packageName));
JSONArray resultsArrayJson = json.getJSONArray("results");
if(resultsArrayJson.length()==0){
// unknown package, probably an abstract dependency
return null;
}
JSONObject resultJson = json.getJSONArray("results").getJSONObject(0);
// get infos except dependencies
name = resultJson.getString("pkgname");
version = resultJson.getString("pkgver");
repo = resultJson.getString("repo");
description = resultJson.getString("pkgdesc");
// if we're at the maximum depth, return the package without its dependencies
if(depth==0){
return new Package(name, version, repo, description, Collections.emptyList());
} else {
// iterate for every package in the list
for (Object depPackageNameObj : resultJson.getJSONArray("depends")) {
// convert object into String
String depPackageName = (String) depPackageNameObj;
// add package into Package List
deps.add(getPackageTree(depPackageName, depth - 1));
}
// TODO this doesn't seem clean
return new Package(name, version, repo, description, deps);
}
}
}

View File

@ -1,13 +0,0 @@
package fr.packageviewer.ArchParser;
import java.util.List;
public class Package extends SearchedPackage {
List<Package> deps;
public Package(String name, String version, String repo, String description, List<Package> deps) {
super(name, version, repo, description);
this.deps = deps;
}
}

View File

@ -1,16 +0,0 @@
package fr.packageviewer.ArchParser;
public class SearchedPackage {
String name;
String version;
String repo;
String description;
public SearchedPackage(String name, String version, String repo, String desciption) {
this.name = name;
this.version = version;
this.repo = repo;
this.description = desciption;
}
}

View File

@ -0,0 +1,153 @@
package fr.packageviewer.distribution;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.net.http.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;
import fr.packageviewer.LoggerManager;
import fr.packageviewer.pack.Package;
import fr.packageviewer.pack.SearchedPackage;
import org.json.*;
public class ArchDistribution implements Distribution {
private static final Logger logger = LoggerManager.getLogger("ArchParser");
/**
* Will return the String json of the package from the Arch Linux API
* @param packageName the package name to get the json from
* @return json of the package
*/
public CompletableFuture<HttpResponse<String>> getPackageFromAPI(String packageName) {
// create a new http client
HttpClient client = HttpClient.newHttpClient();
// and create its url
HttpRequest request = HttpRequest.newBuilder(URI.create("https://archlinux.org/packages/search/json/?name="+packageName)).build();
// send its url and return the string given
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
}
/**
* Search for a package and return a list of packages
* @param packageName the package name to search
* @return
*/
public List<SearchedPackage> searchPackage(String packageName){
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://archlinux.org/packages/search/json/?q="+packageName))
.build();
HttpResponse<String> response;
try{
response = client.send(request, HttpResponse.BodyHandlers.ofString());
}catch(IOException|InterruptedException e){
e.printStackTrace();
return null;
}
JSONObject json = new JSONObject(response.body());
List<SearchedPackage> searchedPackagesList = new ArrayList<>();
// iterate for every package in the list
for (Object searchResultObj : json.getJSONArray("results")) {
// convert object into String
JSONObject searchResultJson = (JSONObject) searchResultObj;
// add package into to list
searchedPackagesList.add(new SearchedPackage(
searchResultJson.getString("pkgname"),
searchResultJson.getString("pkgver"),
searchResultJson.getString("repo"),
searchResultJson.getString("pkgdesc")
));
}
return searchedPackagesList;
}
/**
* Will generate a dependencies tree of depth 'depth' given the package name
* @param packageName the package name to search
* @param depth depth to search dependencies
* @return new Package
*/
public CompletableFuture<Package> getPackageTree(String packageName, int depth) {
// parse the json
var futurePackage = new CompletableFuture<Package>();
logger.fine("Querying package %s from API... (depth=%s)".formatted(packageName, depth));
CompletableFuture<HttpResponse<String>> futureRequest;
try{
futureRequest = getPackageFromAPI(packageName);
}catch(IllegalArgumentException e){
logger.warning("Caught exception for package %s :\n%s".formatted(packageName, e));
return CompletableFuture.completedFuture(null);
}
futureRequest.thenAccept(result->{
List<Package> deps = new ArrayList<>();
String name, version, repo, description;
JSONObject json = new JSONObject(result.body());
JSONArray resultsArrayJson = json.getJSONArray("results");
if(resultsArrayJson.length()==0){
// unknown package, probably an abstract dependency
logger.fine("Completing callback INVALID for package %s (depth=%s)".formatted(packageName, depth));
futurePackage.complete(null);
}
JSONObject resultJson = json.getJSONArray("results").getJSONObject(0);
// get infos except dependencies
name = resultJson.getString("pkgname");
version = resultJson.getString("pkgver");
repo = resultJson.getString("repo");
description = resultJson.getString("pkgdesc");
// if we're at the maximum depth, return the package without its dependencies
if(depth==0){
logger.fine("Completing callback NODEP for package %s (depth=%s)".formatted(packageName, depth));
futurePackage.complete(new Package(name, version, repo, description, Collections.emptyList()));
} else {
// iterate for every package in the list
List<CompletableFuture<Package>> futureDeps = new ArrayList<>();
for (Object depPackageNameObj : resultJson.getJSONArray("depends")) {
// convert object into String
String depPackageName = (String) depPackageNameObj;
// add package into Package List
futureDeps.add(getPackageTree(depPackageName, depth - 1));
}
for(CompletableFuture<Package> future : futureDeps){
try {
deps.add(future.get());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
// TODO this doesn't seem clean
logger.fine("Completing callback DEPS for package %s (depth=%s)".formatted(packageName, depth));
futurePackage.complete(new Package(name, version, repo, description, deps));
}
}).exceptionally((e2->{
logger.warning("Error while fetching package %s (depth=%s) from the API : \n%s".formatted(packageName, depth, e2));
e2.printStackTrace();
futurePackage.complete(null);
return null;
}));
return futurePackage;
}
}

View File

@ -0,0 +1,12 @@
package fr.packageviewer.distribution;
import fr.packageviewer.pack.Package;
import fr.packageviewer.pack.SearchedPackage;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public interface Distribution {
List<SearchedPackage> searchPackage(String packageName);
CompletableFuture<Package> getPackageTree(String packageName, int depth);
}

View File

@ -0,0 +1,21 @@
package fr.packageviewer.pack;
import java.util.List;
public class Package extends SearchedPackage {
private final List<Package> deps;
public List<Package> getDeps() {
return deps;
}
public Package(String name, String version, String repo, String description, List<Package> deps) {
super(name, version, repo, description);
this.deps = deps;
}
@Override
public String toString() {
return "Package{SearchedPackage{%s},deps=%s}".formatted(super.toString(), deps);
}
}

View File

@ -0,0 +1,36 @@
package fr.packageviewer.pack;
public class SearchedPackage {
private final String name;
private final String version;
private final String repo;
private final String description;
public String getName() {
return name;
}
public String getVersion() {
return version;
}
public String getRepo() {
return repo;
}
public String getDescription() {
return description;
}
public SearchedPackage(String name, String version, String repo, String desciption) {
this.name = name;
this.version = version;
this.repo = repo;
this.description = desciption;
}
@Override
public String toString() {
return "SearchedPackage{name=%s,version=%s,repo=%s,description=%s}".formatted(name, version, repo, description);
}
}