diff --git a/gradle.properties b/gradle.properties index 0fe9489..25a7f34 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ ## Project Configurations # Proj Metadata -projVersion = 0.6 +projVersion = 0.7 # Dependencies diff --git a/sekai-cli/build.gradle b/sekai-cli/build.gradle index 0260bd2..4e7c192 100644 --- a/sekai-cli/build.gradle +++ b/sekai-cli/build.gradle @@ -16,8 +16,10 @@ dependencies { implementation rootProject implementation project(":sekai-meta") + implementation project(":sekai-database") implementation "org.postgresql:postgresql:${lib_postgres_driver}" + implementation "com.google.code.gson:gson:${lib_gson}" testImplementation "org.junit.jupiter:junit-jupiter-api:${lib_junit_v}" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${lib_junit_v}" diff --git a/sekai-cli/gradle.properties b/sekai-cli/gradle.properties index ba52310..e055f71 100644 --- a/sekai-cli/gradle.properties +++ b/sekai-cli/gradle.properties @@ -1,7 +1,8 @@ ## Project Configurations # Proj Metadata -moduleVersion = 0.5.2 +moduleVersion = 0.5.3 # dependencies lib_postgres_driver = 42.5.1 +lib_gson = 2.10 diff --git a/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/Config.java b/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/Config.java index b22b7cb..a4065cb 100644 --- a/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/Config.java +++ b/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/Config.java @@ -1,6 +1,6 @@ package cc.sukazyo.sekai_cli; -import cc.sukazyo.sekai_cli.db.PostgresConfig; +import cc.sukazyo.sekai_db.PostgresConfig; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -29,7 +29,7 @@ public class Config { private PostgresConfig db = null; public PostgresConfig db () { - if (db == null) db = new PostgresConfig(this); + if (db == null) db = new PostgresConfig(db_host, db_name, db_schema, db_auth_user, db_auth_pwd); return db; } diff --git a/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/client/Database.java b/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/client/Database.java index 3ff6700..5f4baeb 100644 --- a/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/client/Database.java +++ b/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/client/Database.java @@ -1,8 +1,17 @@ package cc.sukazyo.sekai_cli.client; +import cc.sukazyo.sekai_cli.data_tool.sekai_master_db.Music; +import cc.sukazyo.sekai_scores.Song; +import com.google.gson.JsonIOException; +import com.google.gson.JsonSyntaxException; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; +import java.util.ArrayList; import java.util.List; import static cc.sukazyo.sekai_cli.Log._debug; @@ -12,11 +21,29 @@ public class Database { public static void main (String[] args) { - final List $args = Arrays.asList(args); + final List $args = new ArrayList<>(List.of(args)); final String subcommand = $args.remove(0); if (subcommand.equals("import")) { - if ($args.isEmpty()) { + + int ii; + Charset charset = Charset.defaultCharset(); + if ((ii = $args.indexOf("--charset")) != -1) { + $args.remove(ii); + try { charset = Charset.forName($args.remove(ii)); } + catch (IllegalCharsetNameException e) { + _user("db_import: unknown/illegal charset " + e.getCharsetName()); + _debug(e); + return; + } catch (UnsupportedCharsetException e) { + _user("db_import: unsupported charset by jvm: charset " + e.getCharsetName()); + _debug(e); + return; + } + } + _debug("db_import: will use charset " + charset.displayName()); + + if ($args.size() != 2) { System.out.println(""" database import: currently available types: @@ -29,16 +56,24 @@ public class Database { catch (IndexOutOfBoundsException e) { _user("database import: need a file path."); _debug(e); + return; } switch ($args.remove(0)) { - case "song" -> - _user("type song: WIP"); + case "song" -> { + try { + final Song[] songs = Music.toSongArray(Music.readFrom(file.toFile(), charset)); + } catch (IOException | JsonIOException | JsonSyntaxException e) { + _user("error while parsing song file: " + e.getMessage()); + _debug(e); + } + } case "song-difficulty" -> _user("type song-difficulty: WIP"); default -> _user("unavailable type.\ncurrently available types:\n song\n song-difficulty"); } } + } } diff --git a/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/data_tool/sekai_master_db/Music.java b/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/data_tool/sekai_master_db/Music.java new file mode 100644 index 0000000..c896aa8 --- /dev/null +++ b/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/data_tool/sekai_master_db/Music.java @@ -0,0 +1,65 @@ +package cc.sukazyo.sekai_cli.data_tool.sekai_master_db; + +import cc.sukazyo.sekai_scores.DifficultiesEmpty; +import cc.sukazyo.sekai_scores.Song; +import cc.sukazyo.sekai_scores.SongUnit; +import com.google.gson.Gson; +import com.google.gson.JsonIOException; +import com.google.gson.JsonSyntaxException; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.charset.Charset; +import java.time.*; +import java.util.ArrayList; +import java.util.List; + +public class Music { + + public int id; + public int seq; + public int releaseConditionId; + public String[] categories; + public String title; + public String pronunciation; + public String lyricist; + public String composer; + public String arranger; + public int dancerCount; + public int selfDancerPosition; + public String assetbundleName; + public String liveTalkBackgroundAssetbundleName; + public long publishedAt; + public int liveStageId; + public int filterSec; + + public static Music[] readFrom (File sekaiMusicsFile, Charset charset) throws IOException, JsonIOException, JsonSyntaxException { + return new Gson().fromJson(new FileReader(sekaiMusicsFile, charset), Music[].class); + } + + public SongUnit getUnit () { + return SongUnit.getBySeq((seq/100000) % 10); + } + + public Song toSong () { + return new Song( + id, title, getUnit(), new DifficultiesEmpty(), + null, getOrNull(arranger), getOrNull(composer), getOrNull(lyricist), + null, null, + ZonedDateTime.ofInstant(Instant.ofEpochMilli(publishedAt), ZoneOffset.UTC), + new String[]{} + ); + } + + public static Song[] toSongArray (Music... musics) { + final List songs = new ArrayList<>(); + for (Music i : musics) songs.add(i.toSong()); + return songs.toArray(new Song[0]); + } + + private String getOrNull (String name) { + return name.equals("-") ? null : name; + } + +} diff --git a/sekai-database/build.gradle b/sekai-database/build.gradle index 7c395d7..52c6e30 100644 --- a/sekai-database/build.gradle +++ b/sekai-database/build.gradle @@ -1,19 +1,48 @@ +import java.nio.charset.Charset +import java.nio.charset.StandardCharsets + plugins { id 'java' } -group 'cc.sukazyo' -version projVersion - repositories { mavenCentral() } dependencies { + + compileOnly "com.github.spotbugs:spotbugs-annotations:${lib_spotbugs_v}" + testImplementation "org.junit.jupiter:junit-jupiter-api:${lib_junit_v}" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${lib_junit_v}" + } +final JavaVersion proj_java = JavaVersion.VERSION_17 +final Charset proj_source_encoding = StandardCharsets.UTF_8 + +group 'cc.sukazyo' +version projVersion + test { useJUnitPlatform() -} \ No newline at end of file +} + +java { + + sourceCompatibility proj_java + targetCompatibility proj_java + + withSourcesJar() + +} + +tasks.withType(JavaCompile) { + options.encoding = proj_source_encoding.name() +} + +tasks.withType(Javadoc) { + options.encoding = proj_source_encoding.name() + options.docEncoding = proj_source_encoding.name() + options.charSet = proj_source_encoding.name() +} diff --git a/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/db/PostgresConfig.java b/sekai-database/src/main/java/cc/sukazyo/sekai_db/PostgresConfig.java similarity index 68% rename from sekai-cli/src/main/java/cc/sukazyo/sekai_cli/db/PostgresConfig.java rename to sekai-database/src/main/java/cc/sukazyo/sekai_db/PostgresConfig.java index 8307a01..6e91296 100644 --- a/sekai-cli/src/main/java/cc/sukazyo/sekai_cli/db/PostgresConfig.java +++ b/sekai-database/src/main/java/cc/sukazyo/sekai_db/PostgresConfig.java @@ -1,6 +1,4 @@ -package cc.sukazyo.sekai_cli.db; - -import cc.sukazyo.sekai_cli.Config; +package cc.sukazyo.sekai_db; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -12,36 +10,32 @@ public class PostgresConfig { @Nonnull public final String host; @Nonnull public final String database; - @Nullable public final String struct; + @Nullable public final String schema; @Nonnull public final String user; @Nonnull public final String token; public PostgresConfig ( - @Nonnull String host, @Nonnull String database, @Nullable String struct, + @Nonnull String host, @Nonnull String database, @Nullable String schema, @Nonnull String user, @Nonnull String token ) { this.host = host; this.database = database; - this.struct = struct; + this.schema = schema; this.user = user; this.token = token; } - public PostgresConfig (Config global) { - this(global.db_host, global.db_name, global.db_schema, global.db_auth_user, global.db_auth_pwd); - } - @Override public String toString () { return String.format("jdbc:postgresql://%s/%s", host, database); } - public String struct() { - return struct; + public String schema () { + return schema; } public String table (String table) { - return (struct == null ? "" : '"' + struct() + '"' + ".") + '"' + table + '"'; + return (schema == null ? "" : '"' + schema() + '"' + ".") + '"' + table + '"'; } public Connection connect () throws SQLException { diff --git a/src/main/java/cc/sukazyo/sekai_scores/DifficultiesEmpty.java b/src/main/java/cc/sukazyo/sekai_scores/DifficultiesEmpty.java new file mode 100644 index 0000000..f654a7d --- /dev/null +++ b/src/main/java/cc/sukazyo/sekai_scores/DifficultiesEmpty.java @@ -0,0 +1,16 @@ +package cc.sukazyo.sekai_scores; + +import javax.annotation.Nonnull; +import java.util.function.Consumer; + +public class DifficultiesEmpty implements Difficulties{ + + @Override + public Difficulty[] getAll () { + return new Difficulty[0]; + } + + @Override + public void forEach (@Nonnull Consumer action) {} + +} diff --git a/src/main/java/cc/sukazyo/sekai_scores/SongUnit.java b/src/main/java/cc/sukazyo/sekai_scores/SongUnit.java index 90a99bf..292eb3a 100644 --- a/src/main/java/cc/sukazyo/sekai_scores/SongUnit.java +++ b/src/main/java/cc/sukazyo/sekai_scores/SongUnit.java @@ -30,7 +30,7 @@ public enum SongUnit { _X(-1, "セカイ") ; - public SongUnit getBySeq(int seq) { + public static SongUnit getBySeq(int seq) { return switch (seq) { case 1 -> PIAPRO; case 2 -> LIGHT_SOUND;