diff --git a/Dockerfile b/Dockerfile
index 96aa6c8..476fbf9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -7,6 +7,9 @@ WORKDIR /app/target
FROM openjdk:11-jre-slim
ENV NEO4J_ADDR "localhost:7687"
+ENV PG_URL "localhost:5432/musicbrainz_db"
+ENV PG_USERNAME "musicbrainz"
+ENV PG_PASSWORD "musicbrainz"
COPY --from=build /app/target/music-graph-0.1-jar-with-dependencies.jar /app/
WORKDIR /app/
diff --git a/README.md b/README.md
index afd0ef3..14b3b29 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,9 @@
# music-graph
[](https://www.codefactor.io/repository/github/simon987/music-graph-api)
-[](https://ci.simon987.net/job/music_graph_api/)
API for music-graph.
-This is a read-only wrapper for the data in the Neo4j database, it also serves the cover art, which is stored in a SQLite database.
-
-This project is WIP, as such, it does not implement any kind of rate-limitting or configuration for ports and is mostly undocumented.
+This is a read-only wrapper for the data in the Neo4j database,
+it also serves the album cover art, which is stored in a PostgreSQL database.
diff --git a/pom.xml b/pom.xml
index 8d2fb25..0b21a7c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -59,7 +59,7 @@
org.neo4j.driver
neo4j-java-driver
- 1.7.3
+ 4.0.2
@@ -89,12 +89,14 @@
jaxb-api
2.4.0-b180830.0359
+
com.sun.xml.bind
jaxb-osgi
2.4.0-b180830.0438
+
com.sun.xml.bind
@@ -114,14 +116,15 @@
com.google.guava
guava
- 27.1-jre
+ 29.0-jre
-
+
+
- org.xerial
- sqlite-jdbc
- 3.27.2.1
+ org.postgresql
+ postgresql
+ 42.2.14
\ No newline at end of file
diff --git a/src/main/java/net/simon987/musicgraph/Main.java b/src/main/java/net/simon987/musicgraph/Main.java
index 373a1ae..b684030 100644
--- a/src/main/java/net/simon987/musicgraph/Main.java
+++ b/src/main/java/net/simon987/musicgraph/Main.java
@@ -23,9 +23,13 @@ public class Main {
ResourceConfig rc = new ResourceConfig();
+ String pgUrl = System.getenv("PG_URL");
+ String pgUsername = System.getenv("PG_USERNAME");
+ String pgPassword = System.getenv("PG_PASSWORD");
+
rc.registerInstances(new MusicDatabase());
- rc.registerInstances(new SQLiteCoverArtDatabase("covers.db"));
- rc.registerInstances(new MagickChartBuilder("/dev/shm/im_chart/"));
+ rc.registerInstances(new PostgreSQLCoverArtDatabase(pgUrl, pgUsername, pgPassword));
+// rc.registerInstances(new MagickChartBuilder("/dev/shm/im_chart/"));
rc.registerClasses(Index.class);
rc.registerClasses(ArtistController.class);
@@ -33,7 +37,6 @@ public class Main {
rc.registerClasses(CoverController.class);
rc.registerClasses(TagController.class);
rc.registerClasses(ReleaseController.class);
- rc.registerClasses(ChartController.class);
rc.registerClasses(JacksonFeature.class);
rc.registerClasses(MyExceptionMapper.class);
diff --git a/src/main/java/net/simon987/musicgraph/webapi/AutocompleteLine.java b/src/main/java/net/simon987/musicgraph/entities/AutocompleteLine.java
similarity index 78%
rename from src/main/java/net/simon987/musicgraph/webapi/AutocompleteLine.java
rename to src/main/java/net/simon987/musicgraph/entities/AutocompleteLine.java
index 3c7a0ce..b5ac0e4 100644
--- a/src/main/java/net/simon987/musicgraph/webapi/AutocompleteLine.java
+++ b/src/main/java/net/simon987/musicgraph/entities/AutocompleteLine.java
@@ -1,4 +1,4 @@
-package net.simon987.musicgraph.webapi;
+package net.simon987.musicgraph.entities;
public class AutocompleteLine {
public String name;
diff --git a/src/main/java/net/simon987/musicgraph/entities/Relation.java b/src/main/java/net/simon987/musicgraph/entities/Relation.java
index dadee2e..d59b316 100644
--- a/src/main/java/net/simon987/musicgraph/entities/Relation.java
+++ b/src/main/java/net/simon987/musicgraph/entities/Relation.java
@@ -2,7 +2,7 @@ package net.simon987.musicgraph.entities;
public class Relation {
- public float weight;
+ public double weight;
public long source;
public long target;
}
diff --git a/src/main/java/net/simon987/musicgraph/io/ICoverArtDatabase.java b/src/main/java/net/simon987/musicgraph/io/ICoverArtDatabase.java
index 8fda6d4..a5ad8bc 100644
--- a/src/main/java/net/simon987/musicgraph/io/ICoverArtDatabase.java
+++ b/src/main/java/net/simon987/musicgraph/io/ICoverArtDatabase.java
@@ -11,6 +11,4 @@ public interface ICoverArtDatabase {
* @throws Exception if unexpected error
*/
byte[] getCover(String mbid) throws Exception;
-
- HashMap getCovers(List mbids) throws Exception;
}
diff --git a/src/main/java/net/simon987/musicgraph/io/MusicDatabase.java b/src/main/java/net/simon987/musicgraph/io/MusicDatabase.java
index 39020ca..04607a7 100644
--- a/src/main/java/net/simon987/musicgraph/io/MusicDatabase.java
+++ b/src/main/java/net/simon987/musicgraph/io/MusicDatabase.java
@@ -5,11 +5,11 @@ import com.google.common.collect.ImmutableList;
import net.simon987.musicgraph.entities.*;
import net.simon987.musicgraph.logging.LogManager;
import net.simon987.musicgraph.webapi.AutoCompleteData;
-import net.simon987.musicgraph.webapi.AutocompleteLine;
+import net.simon987.musicgraph.entities.AutocompleteLine;
import org.glassfish.jersey.internal.inject.AbstractBinder;
-import org.neo4j.driver.v1.*;
-import org.neo4j.driver.v1.types.Node;
-import org.neo4j.driver.v1.types.Relationship;
+import org.neo4j.driver.*;
+import org.neo4j.driver.types.Node;
+import org.neo4j.driver.types.Relationship;
import javax.inject.Singleton;
import javax.validation.constraints.Max;
@@ -37,10 +37,10 @@ public class MusicDatabase extends AbstractBinder {
AuthTokens.basic("neo4j", "neo4j"));
}
- private StatementResult query(Session session, String query, Map args) {
+ private Result query(Session session, String query, Map args) {
long start = System.nanoTime();
- StatementResult result = session.run(query, args);
+ Result result = session.run(query, args);
long end = System.nanoTime();
long took = (end - start) / 1000000;
@@ -57,7 +57,7 @@ public class MusicDatabase extends AbstractBinder {
Map params = new HashMap<>();
params.put("mbid", mbid);
- StatementResult result = query(session,
+ Result result = query(session,
"MATCH (a:Artist)-[r:IS_MEMBER_OF]-(b:Artist) " +
"WHERE a.id = $mbid " +
"RETURN a as artist, a {rels: collect(DISTINCT r), nodes: collect(DISTINCT b)} as rank1 " +
@@ -82,7 +82,7 @@ public class MusicDatabase extends AbstractBinder {
try (Session session = driver.session()) {
- StatementResult result = query(session,
+ Result result = query(session,
"MATCH (a:Artist {id: $mbid})" +
"WITH a OPTIONAL MATCH (a)-[:CREDITED_FOR]->(r:Release) " +
"WITH collect({id: ID(r), mbid:r.id, name:r.name, year:r.year, labels:labels(r)}) as releases, a " +
@@ -163,7 +163,7 @@ public class MusicDatabase extends AbstractBinder {
Map params = new HashMap<>();
params.put("mbid", mbid);
- StatementResult result = query(session,
+ Result result = query(session,
"MATCH (a:Artist) " +
"WHERE a.id = $mbid " +
"WITH a OPTIONAL MATCH (a)-[r:IS_RELATED_TO]-(b) " +
@@ -191,7 +191,7 @@ public class MusicDatabase extends AbstractBinder {
params.put("idFrom", idFrom);
params.put("idTo", idTo);
- StatementResult result = query(session,
+ Result result = query(session,
"MATCH p = allShortestPaths(" +
"(:Artist {id: $idFrom})-[r:IS_RELATED_TO*..10]-(:Artist {id:$idTo})) " +
"WHERE ALL (rel in r WHERE rel.weight > 0.10) " +
@@ -220,7 +220,7 @@ public class MusicDatabase extends AbstractBinder {
Map params = new HashMap<>();
params.put("tag_id", id);
- StatementResult result = query(session,
+ Result result = query(session,
"MATCH (t:Tag)-[r:IS_TAGGED]-(a:Artist) " +
"WHERE ID(t) = $tag_id " +
// Is rels really necessary?
@@ -250,7 +250,7 @@ public class MusicDatabase extends AbstractBinder {
Map params = new HashMap<>();
params.put("label_id", id);
- StatementResult result = query(session,
+ Result result = query(session,
"MATCH (l:Label)-[]-(:Release)-[:CREDITED_FOR]-(a:Artist) " +
"WHERE ID(l) = $label_id " +
"RETURN l, {nodes: collect(DISTINCT a)} as rank1 " +
@@ -279,7 +279,7 @@ public class MusicDatabase extends AbstractBinder {
Map params = new HashMap<>();
params.put("label_id", id);
- StatementResult result = query(session,
+ Result result = query(session,
"MATCH (l:Label)-[r:IS_RELATED_TO]-(l2:Label) " +
"WHERE ID(t) = $tag_id " +
"RETURN {rels: collect(DISTINCT r), nodes: collect(DISTINCT t2)} as rank1 " +
@@ -307,7 +307,7 @@ public class MusicDatabase extends AbstractBinder {
Map params = new HashMap<>();
params.put("tag_id", id);
- StatementResult result = query(session,
+ Result result = query(session,
"MATCH (t:Tag)-[r:IS_RELATED_TO]-(t2:Tag) " +
"WHERE ID(t) = $tag_id " +
"RETURN {rels: collect(DISTINCT r), nodes: collect(DISTINCT t2)} as rank1 " +
@@ -329,7 +329,7 @@ public class MusicDatabase extends AbstractBinder {
}
- private void parseRelatedResult(StatementResult result, SearchResult out) {
+ private void parseRelatedResult(Result result, SearchResult out) {
long start = System.nanoTime();
if (result.hasNext()) {
Record row = result.next();
@@ -416,7 +416,7 @@ public class MusicDatabase extends AbstractBinder {
relation.source = rel.startNodeId();
relation.target = rel.endNodeId();
if (rel.containsKey("weight")) {
- relation.weight = rel.get("weight").asFloat();
+ relation.weight = rel.get("weight").asDouble();
}
return relation;
@@ -429,7 +429,7 @@ public class MusicDatabase extends AbstractBinder {
try (Session session = driver.session()) {
- StatementResult result = query(session,
+ Result result = query(session,
"MATCH (release:Release {id: $mbid})-[:CREDITED_FOR]-(a:Artist) " +
"OPTIONAL MATCH (release)-[r:IS_TAGGED]->(t:Tag) " +
"RETURN release {name:release.name, year:release.year," +
@@ -478,7 +478,7 @@ public class MusicDatabase extends AbstractBinder {
AutoCompleteData data = new AutoCompleteData();
- StatementResult result = query(session,
+ Result result = query(session,
"MATCH (a:Artist) " +
"WHERE a.sortname STARTS WITH $prefix " +
"RETURN a ORDER BY a.listeners DESC " +
@@ -499,7 +499,7 @@ public class MusicDatabase extends AbstractBinder {
}
params.put("prefix", prefix.toLowerCase());
- StatementResult tagResult = query(session,
+ Result tagResult = query(session,
"MATCH (t:Tag)-[:IS_TAGGED]-(:Artist) " +
"WHERE t.name STARTS WITH $prefix " +
"RETURN DISTINCT t ORDER BY t.occurrences DESC " +
diff --git a/src/main/java/net/simon987/musicgraph/io/PostgreSQLCoverArtDatabase.java b/src/main/java/net/simon987/musicgraph/io/PostgreSQLCoverArtDatabase.java
new file mode 100644
index 0000000..078d8a7
--- /dev/null
+++ b/src/main/java/net/simon987/musicgraph/io/PostgreSQLCoverArtDatabase.java
@@ -0,0 +1,66 @@
+package net.simon987.musicgraph.io;
+
+import net.simon987.musicgraph.logging.LogManager;
+import org.glassfish.jersey.internal.inject.AbstractBinder;
+
+import java.sql.*;
+import java.util.logging.Logger;
+
+public class PostgreSQLCoverArtDatabase extends AbstractBinder implements ICoverArtDatabase {
+
+ private String url;
+ private String username;
+ private String password;
+
+ private Connection connection;
+
+ private static final Logger logger = LogManager.getLogger();
+
+ public PostgreSQLCoverArtDatabase(String url, String username, String password) {
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ }
+
+ @Override
+ protected void configure() {
+ bind(this).to(ICoverArtDatabase.class);
+ }
+
+ public byte[] getCover(String mbid) throws SQLException {
+
+ try {
+ setupConn();
+
+ PreparedStatement stmt = connection.prepareStatement("SELECT tn FROM mg.covers WHERE mbid::text=?");
+ stmt.setString(1, mbid);
+ ResultSet rs = stmt.executeQuery();
+
+ if (rs.next()) {
+ byte[] bytes = rs.getBytes(1);
+ rs.close();
+ return bytes;
+ } else {
+ rs.close();
+ return null;
+ }
+
+ } catch (SQLException e) {
+ logger.severe(String.format("Exception during cover art query mbid=%s ex=%s",
+ mbid, e.getMessage()));
+ throw e;
+ }
+ }
+
+ private void setupConn() throws SQLException {
+ try {
+ if (connection == null || connection.isClosed()) {
+ logger.fine("Connecting to cover art DB");
+ connection = DriverManager.getConnection("jdbc:postgresql://" + url, username, password);
+ }
+ } catch (SQLException e) {
+ logger.fine("Connecting to cover art DB");
+ connection = DriverManager.getConnection("jdbc:postgresql://" + url, username, password);
+ }
+ }
+}
diff --git a/src/main/java/net/simon987/musicgraph/io/SQLiteCoverArtDatabase.java b/src/main/java/net/simon987/musicgraph/io/SQLiteCoverArtDatabase.java
deleted file mode 100644
index 882d42e..0000000
--- a/src/main/java/net/simon987/musicgraph/io/SQLiteCoverArtDatabase.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package net.simon987.musicgraph.io;
-
-import net.simon987.musicgraph.logging.LogManager;
-import org.glassfish.jersey.internal.inject.AbstractBinder;
-
-import java.sql.*;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Properties;
-import java.util.logging.Logger;
-
-public class SQLiteCoverArtDatabase extends AbstractBinder implements ICoverArtDatabase {
-
- private String dbFile;
- private Connection connection;
-
- private static Logger logger = LogManager.getLogger();
-
- public SQLiteCoverArtDatabase(String dbFile) {
- this.dbFile = dbFile;
- }
-
- @Override
- protected void configure() {
- bind(this).to(ICoverArtDatabase.class);
- }
-
- public byte[] getCover(String mbid) throws SQLException {
-
- try {
- setupConn();
-
- PreparedStatement stmt = connection.prepareStatement("SELECT cover FROM covers WHERE id=?");
- stmt.setString(1, mbid);
- ResultSet rs = stmt.executeQuery();
-
- if (rs.next()) {
- byte[] bytes = rs.getBytes(1);
- rs.close();
- return bytes;
- } else {
- rs.close();
- return null;
- }
-
- } catch (SQLException e) {
- logger.severe(String.format("Exception during cover art query mbid=%s ex=%s",
- mbid, e.getMessage()));
- throw e;
- }
- }
-
- public HashMap getCovers(List mbids) throws SQLException {
-
- HashMap covers = new HashMap<>(mbids.size());
-
- try {
- setupConn();
-
- PreparedStatement stmt = connection.prepareStatement(
- //TODO: sqlite injection
- String.format("SELECT id, cover FROM covers WHERE id IN ('%s')",
- String.join("','", mbids))
- );
- ResultSet rs = stmt.executeQuery();
-
- while (rs.next()) {
- covers.put(rs.getString(1), rs.getBytes(2));
- }
-
- return covers;
-
- } catch (SQLException e) {
- logger.severe(String.format("Exception during cover art query mbid=%s ex=%s",
- mbids, e.getMessage()));
- throw e;
- }
- }
-
- private void setupConn() throws SQLException {
- Properties config = new Properties();
- config.setProperty("open_mode", "1");
-
- try {
- if (connection == null || connection.isClosed()) {
- logger.fine("Connecting to SQLite cover art DB");
- connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile, config);
- }
- } catch (SQLException e) {
- logger.fine("Connecting to SQLite cover art DB");
- connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile, config);
- }
- }
-}
diff --git a/src/main/java/net/simon987/musicgraph/logging/LogManager.java b/src/main/java/net/simon987/musicgraph/logging/LogManager.java
index e4328cf..cc3e168 100644
--- a/src/main/java/net/simon987/musicgraph/logging/LogManager.java
+++ b/src/main/java/net/simon987/musicgraph/logging/LogManager.java
@@ -6,7 +6,7 @@ import java.util.logging.Logger;
public class LogManager {
- private static Logger logger;
+ private static final Logger logger;
static {
logger = Logger.getLogger("music-graph");
diff --git a/src/main/java/net/simon987/musicgraph/webapi/ArtistController.java b/src/main/java/net/simon987/musicgraph/webapi/ArtistController.java
index 68c2a13..5f869e2 100644
--- a/src/main/java/net/simon987/musicgraph/webapi/ArtistController.java
+++ b/src/main/java/net/simon987/musicgraph/webapi/ArtistController.java
@@ -14,7 +14,7 @@ import java.util.logging.Logger;
@Path("/artist")
public class ArtistController {
- private static Logger logger = LogManager.getLogger();
+ private static final Logger logger = LogManager.getLogger();
@Inject
private MusicDatabase db;
diff --git a/src/main/java/net/simon987/musicgraph/webapi/AutoCompleteData.java b/src/main/java/net/simon987/musicgraph/webapi/AutoCompleteData.java
index 421d81b..d82796a 100644
--- a/src/main/java/net/simon987/musicgraph/webapi/AutoCompleteData.java
+++ b/src/main/java/net/simon987/musicgraph/webapi/AutoCompleteData.java
@@ -1,5 +1,7 @@
package net.simon987.musicgraph.webapi;
+import net.simon987.musicgraph.entities.AutocompleteLine;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/src/main/java/net/simon987/musicgraph/webapi/AutocompleteController.java b/src/main/java/net/simon987/musicgraph/webapi/AutocompleteController.java
index de5835a..a81094a 100644
--- a/src/main/java/net/simon987/musicgraph/webapi/AutocompleteController.java
+++ b/src/main/java/net/simon987/musicgraph/webapi/AutocompleteController.java
@@ -14,7 +14,7 @@ import java.util.logging.Logger;
@Path("/")
public class AutocompleteController {
- private static Logger logger = LogManager.getLogger();
+ private static final Logger logger = LogManager.getLogger();
@Inject
private MusicDatabase db;
diff --git a/src/main/java/net/simon987/musicgraph/webapi/ChartController.java b/src/main/java/net/simon987/musicgraph/webapi/ChartController.java
deleted file mode 100644
index af07229..0000000
--- a/src/main/java/net/simon987/musicgraph/webapi/ChartController.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package net.simon987.musicgraph.webapi;
-
-import net.simon987.musicgraph.io.ICoverArtDatabase;
-import net.simon987.musicgraph.io.MusicDatabase;
-
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.NotFoundException;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@Path("/chart")
-public class ChartController {
-
- @Inject
- IChartBuilder chartBuilder;
-
- @Inject
- ICoverArtDatabase coverArtDatabase;
-
- @Inject
- private MusicDatabase musicDatabase;
-
- @GET
- @Produces("image/png")
- public byte[] makeChart() throws Exception {
- var opt = new ChartOptions();
-
- throw new NotFoundException();
-
-// List releases = new ArrayList<>();
-//
-// opt.cols = 4;
-// opt.rows = 5;
-// opt.covers = coverArtDatabase.getCovers(releases);
-// opt.backgroundColor = "blue";
-// opt.details = releases
-// .parallelStream() // Thread-safe?
-// .map(r -> musicDatabase.getReleaseDetails(r))
-// .collect(Collectors.toList());
-//
-// return chartBuilder.makeChart(opt);
- }
-}
diff --git a/src/main/java/net/simon987/musicgraph/webapi/ChartOptions.java b/src/main/java/net/simon987/musicgraph/webapi/ChartOptions.java
deleted file mode 100644
index 0a5d500..0000000
--- a/src/main/java/net/simon987/musicgraph/webapi/ChartOptions.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package net.simon987.musicgraph.webapi;
-
-import net.simon987.musicgraph.entities.ReleaseDetails;
-
-import java.util.HashMap;
-import java.util.List;
-
-public class ChartOptions {
-
- public HashMap covers;
- public List details;
- public int rows;
- public int cols;
- public String backgroundColor;
- public String textColor = "white";
- public String font = "Hack-Regular";
- public String borderColor = "white";
-}
diff --git a/src/main/java/net/simon987/musicgraph/webapi/CoverController.java b/src/main/java/net/simon987/musicgraph/webapi/CoverController.java
index 511840b..3a9b6c0 100644
--- a/src/main/java/net/simon987/musicgraph/webapi/CoverController.java
+++ b/src/main/java/net/simon987/musicgraph/webapi/CoverController.java
@@ -10,7 +10,7 @@ import java.util.logging.Logger;
@Path("/cover/{mbid}")
public class CoverController {
- private static Logger logger = LogManager.getLogger();
+ private static final Logger logger = LogManager.getLogger();
@Inject
private ICoverArtDatabase db;
diff --git a/src/main/java/net/simon987/musicgraph/webapi/IChartBuilder.java b/src/main/java/net/simon987/musicgraph/webapi/IChartBuilder.java
deleted file mode 100644
index eb6b4f8..0000000
--- a/src/main/java/net/simon987/musicgraph/webapi/IChartBuilder.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package net.simon987.musicgraph.webapi;
-
-public interface IChartBuilder {
-
- byte[] makeChart(ChartOptions options) throws Exception;
-}
diff --git a/src/main/java/net/simon987/musicgraph/webapi/Index.java b/src/main/java/net/simon987/musicgraph/webapi/Index.java
index 8cc27c7..a9503c4 100644
--- a/src/main/java/net/simon987/musicgraph/webapi/Index.java
+++ b/src/main/java/net/simon987/musicgraph/webapi/Index.java
@@ -12,7 +12,7 @@ public class Index {
private static final ApiInfo INFO = new ApiInfo(
"music-graph-api",
- "1.1",
+ "2.0",
"/application.wadl",
"https://github.com/simon987/music-graph-api"
);
diff --git a/src/main/java/net/simon987/musicgraph/webapi/LabelController.java b/src/main/java/net/simon987/musicgraph/webapi/LabelController.java
index 5048626..adcf505 100644
--- a/src/main/java/net/simon987/musicgraph/webapi/LabelController.java
+++ b/src/main/java/net/simon987/musicgraph/webapi/LabelController.java
@@ -16,7 +16,7 @@ import java.util.logging.Logger;
@Path("/label")
public class LabelController {
- private static Logger logger = LogManager.getLogger();
+ private static final Logger logger = LogManager.getLogger();
@Inject
private MusicDatabase db;
diff --git a/src/main/java/net/simon987/musicgraph/webapi/MagickChartBuilder.java b/src/main/java/net/simon987/musicgraph/webapi/MagickChartBuilder.java
deleted file mode 100644
index 259b27d..0000000
--- a/src/main/java/net/simon987/musicgraph/webapi/MagickChartBuilder.java
+++ /dev/null
@@ -1,306 +0,0 @@
-package net.simon987.musicgraph.webapi;
-
-import net.simon987.musicgraph.entities.ReleaseDetails;
-import org.glassfish.jersey.internal.inject.AbstractBinder;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
-public class MagickChartBuilder extends AbstractBinder implements IChartBuilder {
-
- private String workspacePath;
- private File workspace;
-
- private static final String[] letters = new String[]{
- "A", "B", "C", "D", "E", "F", "G", "H", "I"
- };
-
- @Override
- protected void configure() {
- bind(this).to(IChartBuilder.class);
- }
-
- public MagickChartBuilder(String workspacePath) {
- this.workspacePath = workspacePath;
- this.workspace = new File(workspacePath);
- }
-
- @Override
- public byte[] makeChart(ChartOptions options) throws Exception {
-
- ProcessBuilder processBuilder = new ProcessBuilder();
- List releases = options.details.stream().map(o -> o.mbid).collect(Collectors.toList());
-
- File chartWorkspace = makeChartWorkspace();
-
- saveCoversToDisk(options, chartWorkspace);
- makeGrid(options, chartWorkspace, releases);
- File header = makeHeader(options, chartWorkspace);
- File side = makeSide(options, chartWorkspace);
-
- // Side + grid
- processBuilder
- .directory(chartWorkspace)
- .command(
- "convert",
- "+append",
- side.toString(),
- "grid.png",
- "grid_with_side.png"
- )
- .start()
- .waitFor();
-
- // Side + grid
- processBuilder
- .directory(chartWorkspace)
- .command(
- "convert",
- "-append",
- "-gravity", "east",
- header.toString(),
- "grid_with_side.png",
- "final_grid.png"
- )
- .start()
- .waitFor();
-
- makeDescription(options, chartWorkspace);
-
- // + description
- processBuilder
- .directory(chartWorkspace)
- .command(
- "convert",
- "+append",
- "-gravity", "south",
- "final_grid.png",
- "description.png",
- "final.png"
- )
- .start()
- .waitFor();
-
-
- FileInputStream file = new FileInputStream(new File(chartWorkspace, "final.png"));
- byte[] chart = file.readAllBytes();
- file.close();
-
- cleanup(chartWorkspace);
-
- return chart;
- }
-
- private void cleanup(File chartWorkspace) {
- String[] entries = chartWorkspace.list();
- if (entries != null) {
- for (String s : entries) {
- File currentFile = new File(chartWorkspace, s);
- currentFile.delete();
- }
- }
- chartWorkspace.delete();
- }
-
- private File makeChartWorkspace() throws IOException {
- String chartId = UUID.randomUUID().toString();
-
- File chartWorkspace = new File(workspacePath, chartId);
- if (!chartWorkspace.mkdir()) {
- throw new IOException(String.format("Could not create chart workspace: %s", chartWorkspace.getAbsolutePath()));
- }
- return chartWorkspace;
- }
-
- private void saveCoversToDisk(ChartOptions options, File chartWorkspace) throws IOException {
- for (ReleaseDetails releaseDetails : options.details) {
- if (options.covers.containsKey(releaseDetails.mbid)) {
- FileOutputStream file = new FileOutputStream(new File(chartWorkspace, releaseDetails.mbid));
- file.write(options.covers.get(releaseDetails.mbid));
- file.close();
- }
- }
- }
-
- private void makeDescription(ChartOptions options, File chartWorkspace)
- throws InterruptedException, IOException {
-
- ProcessBuilder processBuilder = new ProcessBuilder();
-
- for (int i = 0; i < options.rows; i++) {
-
- String desc = formatDescription(options, i);
-
- processBuilder
- .directory(chartWorkspace)
- .command(
- "convert",
- "-size", "620x316",
- "xc:" + options.backgroundColor,
- "-fill", options.textColor,
- "-pointsize", "20",
- "-font", options.font,
- "-annotate", "+0+40", desc,
- String.format("d_%d.png", i)
- )
- .start()
- .waitFor();
- processBuilder
- .directory(chartWorkspace)
- .command(
- "convert",
- "-append",
- "d_*.png",
- "description.png"
- )
- .start()
- .waitFor();
- }
- }
-
- private static String formatDescription(ChartOptions options, int row) {
-
- StringBuilder sb = new StringBuilder();
-
- for (int col = 0; col < options.cols; col++) {
-
- int releaseIndex = row * options.cols + col;
- if (releaseIndex >= options.details.size()) {
- break;
- }
-
- ReleaseDetails release = options.details.get(releaseIndex);
-
- String year = release.year != 0 ? String.format("(%s)", release.year) : "";
-
- if (release.name.length() + release.artist.length() < 40) {
- sb.append(String.format("%s%d %s - %s %s\n",
- letters[row], col+1,
- release.name, release.artist, year));
- } else {
- sb.append(String.format("%s%d %s -\n\t\t\t %s %s\n",
- letters[row], col+1,
- release.name, release.artist, year));
- }
- }
- return sb.toString();
- }
-
- private void makeGrid(ChartOptions options, File chartWorkspace, List releases)
- throws InterruptedException, IOException {
-
- ProcessBuilder processBuilder = new ProcessBuilder();
-
- List cmd = new ArrayList<>();
- cmd.add("montage");
- cmd.addAll(releases);
- cmd.add("-tile");
- cmd.add(String.format("%dx%d", options.cols, options.rows));
- cmd.add("-background");
- cmd.add(options.backgroundColor);
- cmd.add("-border");
- cmd.add("1");
- cmd.add("-bordercolor");
- cmd.add(options.borderColor);
- cmd.add("-geometry");
- cmd.add("256x256+30+30");
- cmd.add("grid.png");
-
- processBuilder
- .directory(chartWorkspace)
- .command(cmd)
- .start()
- .waitFor();
- }
-
- private File makeSide(ChartOptions options, File chartWorkSpace)
- throws InterruptedException, IOException {
-
- File sideFile = new File(chartWorkSpace, "side.png");
-
- ProcessBuilder processBuilder = new ProcessBuilder();
-
- for (int i = 0; i < options.rows; i++) {
- processBuilder
- .directory(chartWorkSpace)
- .command(
- "convert",
- "-background", options.backgroundColor,
- "-gravity", "east",
- "-size", "60x256",
- "-fill", options.textColor,
- "-pointsize", "64",
- "-font", options.font,
- "-strip",
- String.format("label:%s", letters[i]),
- String.format("s_%d.png", i + 1)
- )
- .start()
- .waitFor();
- }
-
- processBuilder
- .directory(chartWorkSpace)
- .command(
- "montage",
- "-tile", "1x",
- "-background", options.backgroundColor,
- "-geometry", "+0+31",
- "s_*.png",
- sideFile.toString()
- )
- .start()
- .waitFor();
-
- return sideFile;
- }
-
- private File makeHeader(ChartOptions options, File chartWorkspace)
- throws InterruptedException, IOException {
-
- File headerFile = new File(chartWorkspace, "header.png");
- ProcessBuilder processBuilder = new ProcessBuilder();
-
- // Header
- for (int i = 1; i <= options.cols; i++) {
- processBuilder
- .directory(chartWorkspace)
- .command(
- "convert",
- "-background", options.backgroundColor,
- "-gravity", "south",
- "-size", "256x80",
- "-fill", options.textColor,
- "-chop", "0x12",
- "-pointsize", "64",
- "-font", options.font,
- "-strip",
- String.format("label:%d", i),
- String.format("h_%d.png", i)
- )
- .start()
- .waitFor();
- }
-
- processBuilder
- .directory(chartWorkspace)
- .command(
- "montage",
- "-tile", "x1",
- "h_*.png",
- "-background", options.backgroundColor,
- "-geometry", "+31+0",
- headerFile.toString()
- )
- .start()
- .waitFor();
-
- return headerFile;
- }
-}
diff --git a/src/main/java/net/simon987/musicgraph/webapi/TagController.java b/src/main/java/net/simon987/musicgraph/webapi/TagController.java
index f098cb3..be244d1 100644
--- a/src/main/java/net/simon987/musicgraph/webapi/TagController.java
+++ b/src/main/java/net/simon987/musicgraph/webapi/TagController.java
@@ -16,7 +16,7 @@ import java.util.logging.Logger;
@Path("/tag")
public class TagController {
- private static Logger logger = LogManager.getLogger();
+ private static final Logger logger = LogManager.getLogger();
@Inject
private MusicDatabase db;