diff --git a/.idea/git_toolbox_prj.xml b/.idea/git_toolbox_prj.xml new file mode 100644 index 0000000..02b915b --- /dev/null +++ b/.idea/git_toolbox_prj.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/player.api/assets/seed.cypher b/player.api/assets/seed.cypher new file mode 100644 index 0000000..fa6ce3b --- /dev/null +++ b/player.api/assets/seed.cypher @@ -0,0 +1,100 @@ +// === MEMBERS === +CREATE (:Member {name: "Onye"}); +CREATE (:Member {name: "Eric Westerhold"}); +CREATE (:Member {name: "Andrew Manzaneres"}); + +// === CORPS === +CREATE (:Corps {name: "Bluecoats"}); +CREATE (:Corps {name: "Blue Devils"}); + +// === SHOWS === +CREATE (:Show {title: "To Look For America", year: 2017}); +CREATE (:Show {title: "Kinetic Noise", year: 2015}); +CREATE (:Show {title: "Re:Write of Spring", year: 2013}); + +// === COMPOSERS === +MERGE (ps:Composer {name: "Paul Simon"}) +MERGE (rw:Composer {name: "Rufus Wainwright"}) +MERGE (de:Composer {name: "Duke Ellington"}) +MERGE (is:Composer {name: "Igor Stravinsky"}) +MERGE (sb:Composer {name: "Steven Bryant"}) +MERGE (lc:Composer {name: "Leonard Cohen"}) +MERGE (sr:Composer {name: "Steve Reich"}) +MERGE (ja:Composer {name: "John Adams"}) +MERGE (jan:Composer {name: "John Anderson"}) +MERGE (bi:Composer {name: "Bon Iver"}) +MERGE (mg:Composer {name: "Michael Gordon"}) +MERGE (tb:Composer {name: "The Books"}) +MERGE (uz:Composer {name: "Univers Zero"}) + +// === PIECES === +MERGE (a:Piece {title: "America"})-[:COMPOSED_BY]->(ps) +MERGE (ag:Piece {title: "Agnus Dei"})-[:COMPOSED_BY]->(rw) +MERGE (sp:Piece {title: "Spring"})-[:COMPOSED_BY]->(de) +MERGE (eb:Piece {title: "Ebony Concerto"})-[:COMPOSED_BY]->(is) +MERGE (cc:Piece {title: "Concerto"})-[:COMPOSED_BY]->(sb) +MERGE (hl:Piece {title: "Hallelujah"})-[:COMPOSED_BY]->(lc) +MERGE (cl:Piece {title: "City Life"})-[:COMPOSED_BY]->(sr) +MERGE (rs:Piece {title: "The Rite of Spring"})-[:COMPOSED_BY]->(is) +MERGE (sl:Piece {title: "Shaker Loops"})-[:COMPOSED_BY]->(ja) +MERGE (sl)-[:COMPOSED_BY]->(jan) +MERGE (ec:Piece {title: "Electric Counterpoint"})-[:COMPOSED_BY]->(sr) +MERGE (wd:Piece {title: "Woods"})-[:COMPOSED_BY]->(bi) +MERGE (gt:Piece {title: "Gene Takes A Drink"})-[:COMPOSED_BY]->(mg) +MERGE (ad:Piece {title: "An Animated Description Of Mr Maps"})-[:COMPOSED_BY]->(tb) +MERGE (ds:Piece {title: "Dense"})-[:COMPOSED_BY]->(uz); + +// === RELATIONSHIPS: Shows → Corps === +MATCH (s1:Show {title: "To Look For America"}), (c1:Corps {name: "Bluecoats"}) +CREATE (s1)-[:FIELD_BY]->(c1); + +MATCH (s2:Show {title: "Kinetic Noise"}), (c2:Corps {name: "Bluecoats"}) +CREATE (s2)-[:FIELD_BY]->(c2); + +MATCH (s3:Show {title: "Re:Write of Spring"}), (c3:Corps {name: "Blue Devils"}) +CREATE (s3)-[:FIELD_BY]->(c3); + +// === RELATIONSHIPS: Members → Shows === +MATCH (m1:Member {name: "Onye"}), (s1:Show {title: "To Look For America"}) +CREATE (m1)-[:PERFORMED_IN]->(s1); + +MATCH (m2:Member {name: "Eric Westerhold"}), (s2:Show {title: "Kinetic Noise"}) +CREATE (m2)-[:PERFORMED_IN]->(s2); + +MATCH (m3:Member {name: "Andrew Manzaneres"}), (s3:Show {title: "Re:Write of Spring"}) +CREATE (m3)-[:PERFORMED_IN]->(s3); + +// === RELATIONSHIPS: Shows → Pieces === +MATCH (s:Show {title: "To Look For America"}), + (a:Piece {title: "America"}), + (ag:Piece {title: "Agnus Dei"}), + (sp:Piece {title: "Spring"}), + (eb:Piece {title: "Ebony Concerto"}), + (cc:Piece {title: "Concerto"}), + (hl:Piece {title: "Hallelujah"}), + (cl:Piece {title: "City Life"}) +CREATE (s)-[:FEATURED]->(a), + (s)-[:FEATURED]->(ag), + (s)-[:FEATURED]->(sp), + (s)-[:FEATURED]->(eb), + (s)-[:FEATURED]->(cc), + (s)-[:FEATURED]->(hl), + (s)-[:FEATURED]->(cl); + +MATCH (s:Show {title: "Re:Write of Spring"}), + (rs:Piece {title: "The Rite of Spring"}) +CREATE (s)-[:FEATURED]->(rs); + +MATCH (s:Show {title: "Kinetic Noise"}), + (sl:Piece {title: "Shaker Loops"}), + (ec:Piece {title: "Electric Counterpoint"}), + (wd:Piece {title: "Woods"}), + (gt:Piece {title: "Gene Takes A Drink"}), + (ad:Piece {title: "An Animated Description Of Mr Maps"}), + (ds:Piece {title: "Dense"}) +CREATE (s)-[:FEATURED]->(sl), + (s)-[:FEATURED]->(ec), + (s)-[:FEATURED]->(wd), + (s)-[:FEATURED]->(gt), + (s)-[:FEATURED]->(ad), + (s)-[:FEATURED]->(ds); diff --git a/player.api/src/main/java/Scratch.java b/player.api/src/main/java/Scratch.java new file mode 100644 index 0000000..5f9ee8a --- /dev/null +++ b/player.api/src/main/java/Scratch.java @@ -0,0 +1,29 @@ +import com.dci.aaronic.player.io.DCIFileMetadataContainer; +import com.dci.aaronic.player.io.DCIFileWriter; + +import java.io.File; +import java.io.IOException; + +public class Scratch { + + public static void main(String[] args) { + File test_file = new File("C:\\Users\\kacar\\Desktop\\Data Projects\\DCIPlayer\\player.api\\player.api\\assets\\Bluecoats_2015_Kinetic_Noise.mp4"); + DCIFileMetadataContainer metadata = null; + try { + metadata = DCIFileMetadataContainer.extract(test_file.getName()); + + System.out.println(metadata); + } + catch (IOException e) { + e.printStackTrace(); + } + + try { + File testOut = new File("C:\\Users\\kacar\\Desktop\\Data Projects\\DCIPlayer\\player.api\\player.api\\assets\\Bluecoats_2015_Kinetic_Noise.dci"); + DCIFileWriter writer = new DCIFileWriter(); + writer.write(test_file, metadata, testOut); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/api/Application.java b/player.api/src/main/java/com/dci/aaronic/player/api/Application.java new file mode 100644 index 0000000..259387e --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/api/Application.java @@ -0,0 +1,13 @@ +package com.dci.aaronic.player.api; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileMetadataContainer.java b/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileMetadataContainer.java new file mode 100644 index 0000000..93cdf4d --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileMetadataContainer.java @@ -0,0 +1,91 @@ +package com.dci.aaronic.player.io; + +import com.dci.aaronic.player.models.Corps; +import com.dci.aaronic.player.utils.Utils; + +import java.io.File; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DCIFileMetadataContainer { + public int year; + public String title; + public String corps; + + public DCIFileMetadataContainer() {} + + public DCIFileMetadataContainer(int year, String title, String corps) { + this.year = year; + this.title = title; + this.corps = corps; + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getCorps() { + return corps; + } + + public void setCorps(String corps) { + this.corps = corps; + } + + public static DCIFileMetadataContainer extract(String fileName) throws IOException { + Pattern yearPattern = Pattern.compile("\\d{4}"); + Matcher yearMatcher = yearPattern.matcher(fileName); + String year = null; + if (yearMatcher.find()) { + year = yearMatcher.group(); + } + String foundCorps = null; + for (Corps corps: Utils.ALL_CORPS) { + if (fileName.contains(corps.getName())) { + foundCorps = corps.getName(); + break; + } + } + + String fileExtension = fileName.substring(fileName.lastIndexOf(".")); + + String title = fileName; + if (foundCorps != null) { + title = title.replace(foundCorps, ""); + } + + if (year != null) { + title = title.replace(year, ""); + } + + if (fileExtension != null) { + title = title.replace(fileExtension, ""); + } + + title = title.replace("_", " "); + title = title.trim(); + return new DCIFileMetadataContainer(Integer.parseInt(year), title, foundCorps); + } + + public String toString() { + return "DCIFileMetadataContainer{" + + "year=" + year + + ", title='" + title + '\'' + + ", corps='" + corps + '\'' + + '}'; + } + +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileMetadataSerializer.java b/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileMetadataSerializer.java new file mode 100644 index 0000000..1c2fa66 --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileMetadataSerializer.java @@ -0,0 +1,28 @@ +package com.dci.aaronic.player.io; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; + +public class DCIFileMetadataSerializer { + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + public static byte[] serialize(DCIFileMetadataContainer metadata) throws IOException { + try { + return objectMapper.writeValueAsBytes(metadata); + } + catch (IOException e) { + throw new IOException("Error serializing metadata: " + e); + } + } + + public static DCIFileMetadataContainer deserialize(byte[] bytes) throws IOException { + try { + return objectMapper.readValue(bytes, DCIFileMetadataContainer.class); + } + catch (IOException e) { + throw new IOException("Error deserializing metadata: " + e); + } + } +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileReader.java b/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileReader.java new file mode 100644 index 0000000..d426b34 --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileReader.java @@ -0,0 +1,36 @@ +package com.dci.aaronic.player.io; + +import java.io.*; +import java.util.Arrays; +import java.util.Map; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class DCIFileReader { + + private static final byte[] MAGIC = ".DCI".getBytes(); + private final ObjectMapper objectMapper = new ObjectMapper(); + + public void read(File file) throws IOException{ + try (DataInputStream in = new DataInputStream(new FileInputStream(file))) { + byte[] magic = new byte[MAGIC.length]; + in.readFully(magic); + if (!Arrays.equals(magic, MAGIC)) { + throw new IOException("Header mismatch - not a valid .DCI file"); + } + int version = in.readInt(); + if (version != 1) { + throw new IOException("Unsupported version: " + version); + } + int metaLength = in.readInt(); + byte[] meta = new byte[metaLength]; + in.readFully(meta); + Map metaMap = objectMapper.readValue(meta, Map.class); // <1> + + System.out.println(metaMap); + + byte[] content = in.readAllBytes(); + } + + } +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileWriter.java b/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileWriter.java new file mode 100644 index 0000000..f46d22f --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/io/DCIFileWriter.java @@ -0,0 +1,28 @@ +package com.dci.aaronic.player.io; + +import jdk.jshell.spi.ExecutionControl; + +import java.io.*; +import java.nio.file.Files; + +//Convert MP4 to DCI + +public class DCIFileWriter { + + private static final byte[] MAGIC = ".DCI".getBytes(); + + public void write(File file, DCIFileMetadataContainer metadata, File outputFile) throws IOException { + byte[] content = Files.readAllBytes(file.toPath()); + try (DataOutputStream out = new DataOutputStream(new FileOutputStream(outputFile))) { + out.write(MAGIC); + out.writeInt(1); + byte[] meta = DCIFileMetadataSerializer.serialize(metadata); + out.writeInt(meta.length); + out.write(meta); + out.write(content); + } + catch (IOException e) { + System.out.println("Error creating DCI file: " + e); + } + } +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/models/Corps.java b/player.api/src/main/java/com/dci/aaronic/player/models/Corps.java new file mode 100644 index 0000000..8e0aad0 --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/models/Corps.java @@ -0,0 +1,22 @@ +package com.dci.aaronic.player.models; + +public class Corps { + public String name; + public int foundingYear; + public String homeCity; + public String homeState; + public String[] aliases; + + + public Corps(String name, int foundingYear, String homeCity, String homeState, String[] aliases) { + this.name = name; + this.foundingYear = foundingYear; + this.homeCity = homeCity; + this.homeState = homeState; + this.aliases = aliases; + } + + public String getName() { + return name; + } +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/models/CorpsProgram.java b/player.api/src/main/java/com/dci/aaronic/player/models/CorpsProgram.java new file mode 100644 index 0000000..c3477dc --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/models/CorpsProgram.java @@ -0,0 +1,8 @@ +package com.dci.aaronic.player.models; + +public class CorpsProgram { + + private Corps _corps; + private MusicSelection[] _reportoires; + private int _year; +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/models/CorpsStaff.java b/player.api/src/main/java/com/dci/aaronic/player/models/CorpsStaff.java new file mode 100644 index 0000000..69965b0 --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/models/CorpsStaff.java @@ -0,0 +1,10 @@ +package com.dci.aaronic.player.models; + +public class CorpsStaff { + + public Member President; + public Member BrassCaptionHead; + public Member PercussionCaptionHead; + public Member VisualCaptionHead; + +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/models/Member.java b/player.api/src/main/java/com/dci/aaronic/player/models/Member.java new file mode 100644 index 0000000..942e093 --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/models/Member.java @@ -0,0 +1,4 @@ +package com.dci.aaronic.player.models; + +public class Member { +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/models/MusicSelection.java b/player.api/src/main/java/com/dci/aaronic/player/models/MusicSelection.java new file mode 100644 index 0000000..fcad4dd --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/models/MusicSelection.java @@ -0,0 +1,9 @@ +package com.dci.aaronic.player.models; + +public class MusicSelection { + + public String title; + public String subtitle; + public String composer; + +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/models/Section.java b/player.api/src/main/java/com/dci/aaronic/player/models/Section.java new file mode 100644 index 0000000..d11b01f --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/models/Section.java @@ -0,0 +1,31 @@ +package com.dci.aaronic.player.models; + +public enum Section { + BRASS, + PERCUSSION, + COLORGUARD; + + public enum Subsection { + TRUMPETS(BRASS), + MELLOPHONES(BRASS), + BARITONES(BRASS), + CONTRAS(BRASS), + SNARES(PERCUSSION), + TENORS(PERCUSSION), + BASSES(PERCUSSION), + CYMBALS(PERCUSSION), + FRONTENSEMBLE(PERCUSSION), + FLAGS(COLORGUARD), + RIFLESANDSABRES(COLORGUARD); + + private final Section _section; + + Subsection(Section section) { + _section = section; + } + + public Section getSection() { + return _section; + } + } +} diff --git a/player.api/src/main/java/com/dci/aaronic/player/utils/Utils.java b/player.api/src/main/java/com/dci/aaronic/player/utils/Utils.java new file mode 100644 index 0000000..8297ce4 --- /dev/null +++ b/player.api/src/main/java/com/dci/aaronic/player/utils/Utils.java @@ -0,0 +1,19 @@ +package com.dci.aaronic.player.utils; + +import com.dci.aaronic.player.models.Corps; + +import java.util.List; + +public class Utils { + + private Utils() {} + + public static List ALL_CORPS = List.of( + new Corps("Bluecoats", 1974, "Canton", "Ohio", + new String[]{ + "Bluecoats", + "Bloo" + }) + ); + +} diff --git a/player.api/src/test/java/com/dci/aaronic/player/api/ApplicationTests.java b/player.api/src/test/java/com/dci/aaronic/player/api/ApplicationTests.java new file mode 100644 index 0000000..a939ba0 --- /dev/null +++ b/player.api/src/test/java/com/dci/aaronic/player/api/ApplicationTests.java @@ -0,0 +1,13 @@ +package com.dci.aaronic.player.api; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ApplicationTests { + + @Test + void contextLoads() { + } + +}