Initialer Commit
This commit is contained in:
367
.classpath
Normal file
367
.classpath
Normal file
@@ -0,0 +1,367 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
<classpathentry output="bin/main" kind="src" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry output="bin/main" kind="src" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-web/3.2.3/e91bf4f7d1f176e3809365df66b57b6920ce2e0a/spring-boot-starter-web-3.2.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-web/3.2.3/bf2b775d4f4e6349129c64de30939a5493779706/spring-boot-starter-web-3.2.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.10.1/982a90132e942f302e6fe79d6e78c4bc2e998569/gson-2.10.1-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.10.1/b3add478d4382b78ea20b1671390a858002feb6c/gson-2.10.1.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-json/3.2.3/7c44e81cf7a91455d41c1dcb1ca4dfaeacbfa4f9/spring-boot-starter-json-3.2.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-json/3.2.3/c71ec683425f09b7a213358d3b22959d929d1108/spring-boot-starter-json-3.2.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter/3.2.3/cc234d196c7403f924849a6db881f507b47caccb/spring-boot-starter-3.2.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter/3.2.3/15f3e03b0fd9570f90bdce9651610cc152534cf4/spring-boot-starter-3.2.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-tomcat/3.2.3/2e0beb1969719a944d2ffd39b64d188345abc70b/spring-boot-starter-tomcat-3.2.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-tomcat/3.2.3/ac392404d41766194b8fce6834c71879f9e8f479/spring-boot-starter-tomcat-3.2.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-webmvc/6.1.4/5312515a4e711152ab20cb53eefce85c885e1ff5/spring-webmvc-6.1.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-webmvc/6.1.4/e7aad7c53e05c8772209e915029e121262a7bc33/spring-webmvc-6.1.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-web/6.1.4/41a915620b58a36536852b7fb384804750df6ba/spring-web-6.1.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-web/6.1.4/b237532e03330a7cf8f66dc147e62bbbe44c702f/spring-web-6.1.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-autoconfigure/3.2.3/d89d997c7ae3b4fd0303b598c1dd20b8709f16a0/spring-boot-autoconfigure-3.2.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-autoconfigure/3.2.3/59db74eb4196885bb5a149417ab1ab51dc9b6952/spring-boot-autoconfigure-3.2.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot/3.2.3/6aafb01f8e3d3a968f6f3630c86f4acab9d6bf5/spring-boot-3.2.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot/3.2.3/b4aa6e3fdc4078fee4a4b9d702d9cc64e3fad1d4/spring-boot-3.2.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-logging/3.2.3/d89e2afa31fcdd4b4d3c65aa68ba7b93d7823cec/spring-boot-starter-logging-3.2.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-logging/3.2.3/c186015229d7f5cbd30ea99bf903a8cede6d849f/spring-boot-starter-logging-3.2.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/jakarta.annotation/jakarta.annotation-api/2.1.1/3beea3ed2e687d9bd8a78c00e18951fffccefe90/jakarta.annotation-api-2.1.1-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/jakarta.annotation/jakarta.annotation-api/2.1.1/48b9bda22b091b1f48b13af03fe36db3be6e1ae3/jakarta.annotation-api-2.1.1.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-context/6.1.4/b926271c28c9a70beadfcafd210b0fca465d5351/spring-context-6.1.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-context/6.1.4/765316bef55e41e4523f9b2780b8721ce5dd0fe2/spring-context-6.1.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-aop/6.1.4/9c23baecaa4dcf4cd52237d1935e96943ce671a9/spring-aop-6.1.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-aop/6.1.4/26ae2c9e7f69b0235a2faca1c58416c51eaebef6/spring-aop-6.1.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-beans/6.1.4/499ccf59eedb263d50d91cc00b9d34a5d70097f5/spring-beans-6.1.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-beans/6.1.4/e311cc9937d522a1051622580b4a2c250fc74164/spring-beans-6.1.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-expression/6.1.4/179e83febf6982faa42e48086df0b5f16bc0558f/spring-expression-6.1.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-expression/6.1.4/a1f2e3af83c7222b7f95f68a8e0666fdcceb35e1/spring-expression-6.1.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-core/6.1.4/a602755e3e97ef0bc40952636ba934433a71f61/spring-core-6.1.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-core/6.1.4/3b4dde8f55c3d5d4e948de64b866d7bb27e5a8d4/spring-core-6.1.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.yaml/snakeyaml/2.2/575a7915b847393207642575c139177ac2b2ac23/snakeyaml-2.2-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.yaml/snakeyaml/2.2/3af797a25458550a16bf89acc8e4ab2b7f2bfce0/snakeyaml-2.2.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.15.4/374791e1cb74eff66f761325affac3b3b2c8a1a1/jackson-datatype-jsr310-2.15.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.15.4/7de629770a4559db57128d35ccae7d2fddd35db3/jackson-datatype-jsr310-2.15.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.module/jackson-module-parameter-names/2.15.4/4c1d3cc9f6a69cbb03d3517085c92172ddb5fbd3/jackson-module-parameter-names-2.15.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.module/jackson-module-parameter-names/2.15.4/e654497a08359db2521b69b5f710e00836915d8c/jackson-module-parameter-names-2.15.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-annotations/2.15.4/704650e6ff1479d7847d61e9d578c1c5a9951f76/jackson-annotations-2.15.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-annotations/2.15.4/5223ea5a9bf52cdc9c5e537a0e52f2432eaf208b/jackson-annotations-2.15.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-core/2.15.4/1e96cdf3ba633b07b8d3cb514e9e5d899c8965f/jackson-core-2.15.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-core/2.15.4/aebe84b45360debad94f692a4074c6aceb535fa0/jackson-core-2.15.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.datatype/jackson-datatype-jdk8/2.15.4/1d5d9f86752c0c7d0d740e4cbb8b636b2cac5e5/jackson-datatype-jdk8-2.15.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.datatype/jackson-datatype-jdk8/2.15.4/694777f182334a21bf1aeab1b04cc4398c801f3f/jackson-datatype-jdk8-2.15.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-databind/2.15.4/b45d6e020c2dc43efac1fd1333a349eeafa9a8de/jackson-databind-2.15.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-databind/2.15.4/560309fc381f77d4d15c4a4cdaa0db5025c4fd13/jackson-databind-2.15.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-websocket/10.1.19/949b0e6a2958c38d5e31c99a43520449cad06f7c/tomcat-embed-websocket-10.1.19-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-websocket/10.1.19/adf4710fac2471236f8a466ca678cdf7e6a8257c/tomcat-embed-websocket-10.1.19.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-core/10.1.19/be0e8644fe92a7333f59996ce214db7f893c9166/tomcat-embed-core-10.1.19-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-core/10.1.19/3dbbca8acbd4dd6a137c3d6f934a2931512b42ce/tomcat-embed-core-10.1.19.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-el/10.1.19/a4024787c4d3d5ca3f3176e0e14e8f6aa0a31db6/tomcat-embed-el-10.1.19-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-el/10.1.19/c61a582c391aca130884a5421deedfe1a96c7415/tomcat-embed-el-10.1.19.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/io.micrometer/micrometer-observation/1.12.3/8aeac366ae3ac29958335b06801f163c06ec39d0/micrometer-observation-1.12.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/io.micrometer/micrometer-observation/1.12.3/105f768c211564fcebe4d79419bda4ebef0d0ac7/micrometer-observation-1.12.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.4.14/1b0b0b96069e3ec3b4d8e5cbffc0a56e633063de/logback-classic-1.4.14-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.4.14/d98bc162275134cdf1518774da4a2a17ef6fb94d/logback-classic-1.4.14.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-to-slf4j/2.21.1/31272b58321454b5d5a565f1e782ed4448ab3312/log4j-to-slf4j-2.21.1-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-to-slf4j/2.21.1/d77b2ba81711ed596cd797cc2b5b5bd7409d841c/log4j-to-slf4j-2.21.1.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.slf4j/jul-to-slf4j/2.0.12/7c0451bb352ce3f1ed9a0a35355a132ec08ba4c7/jul-to-slf4j-2.0.12-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.slf4j/jul-to-slf4j/2.0.12/eb5f48f782b41cc881b0bf1fb4d88ae2ff6d5b93/jul-to-slf4j-2.0.12.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-jcl/6.1.4/24e6bcbd5fb0d950142f7792df7b1ecfc5ecd5b0/spring-jcl-6.1.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-jcl/6.1.4/a244bd674a5431dfdce68d28cdf857104e6fff67/spring-jcl-6.1.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/io.micrometer/micrometer-commons/1.12.3/1da4cccb967f16fbd175ea2bbddd2985e01774d5/micrometer-commons-1.12.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/io.micrometer/micrometer-commons/1.12.3/83add2dda5cdc811fefb83e858c7412a176fe5b1/micrometer-commons-1.12.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-core/1.4.14/7d9dcce57ba091e1e4b4793b244508ea28f52b48/logback-core-1.4.14-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-core/1.4.14/4d3c2248219ac0effeb380ed4c5280a80bf395e8/logback-core-1.4.14.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/2.0.12/c2824e780c88689134cb99fb33c8a4ed3de0f406/slf4j-api-2.0.12-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/2.0.12/48f109a2a6d8f446c794f3e3fa0d86df0cdfa312/slf4j-api-2.0.12.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-api/2.21.1/7c87eb50e74855cd86f92bf370300b60ceef4a0b/log4j-api-2.21.1-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-api/2.21.1/74c65e87b9ce1694a01524e192d7be989ba70486/log4j-api-2.21.1.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-test/3.2.3/a4546d463e3f68794a061cc2fd01769bdd088d33/spring-boot-starter-test-3.2.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-test/3.2.3/edfce43fbd303d556f3951af65dfb6e335d8230e/spring-boot-starter-test-3.2.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-test-autoconfigure/3.2.3/e8d56afca760da4184b74a93fd7a30e753d728f6/spring-boot-test-autoconfigure-3.2.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-test-autoconfigure/3.2.3/ea2e1778142fc8a05bd9325b433b13fe0a6845c1/spring-boot-test-autoconfigure-3.2.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-test/3.2.3/74a985e247a2655d8fe156dcd28fd3199ae3ddcd/spring-boot-test-3.2.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-test/3.2.3/4f440305c921caa9eb11624c1c6fa8fcc5200a64/spring-boot-test-3.2.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/com.jayway.jsonpath/json-path/2.9.0/a1ae84a6b97263c7ea566dfa73d5ac2271743e44/json-path-2.9.0-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/com.jayway.jsonpath/json-path/2.9.0/37fe2217f577b0b68b18e62c4d17a8858ecf9b69/json-path-2.9.0.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/jakarta.xml.bind/jakarta.xml.bind-api/4.0.1/7723d0945b45888b9d8af6e0358a5f5d5cdec2fd/jakarta.xml.bind-api-4.0.1-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/jakarta.xml.bind/jakarta.xml.bind-api/4.0.1/ca2330866cbc624c7e5ce982e121db1125d23e15/jakarta.xml.bind-api-4.0.1.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/net.minidev/json-smart/2.5.0/7f51740e5d2aa84831af62084d5ae98a51fcb61d/json-smart-2.5.0-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/net.minidev/json-smart/2.5.0/57a64f421b472849c40e77d2e7cce3a141b41e99/json-smart-2.5.0.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.assertj/assertj-core/3.24.2/76c425ccc878f91e347fa3cb0d686772679b66e2/assertj-core-3.24.2-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.assertj/assertj-core/3.24.2/ebbf338e33f893139459ce5df023115971c2786f/assertj-core-3.24.2.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.awaitility/awaitility/4.2.0/359e52d6a80b3d12fb08b0e665f15ce334d2c7a3/awaitility-4.2.0-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.awaitility/awaitility/4.2.0/2c39784846001a9cffd6c6b89c78de62c0d80fb8/awaitility-4.2.0.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest/2.2/a0a13cfc629420efb587d954f982c4c6a100da25/hamcrest-2.2-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest/2.2/1820c0968dba3a11a1b30669bb1f01978a91dedc/hamcrest-2.2.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-params/5.10.2/1add8e4310a408675f46eae8acafe6b2b72232e5/junit-jupiter-params-5.10.2-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-params/5.10.2/359132c82a9d3fa87a325db6edd33b5fdc67a3d8/junit-jupiter-params-5.10.2.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-api/5.10.2/b281dbb5921ce56b37b6e07a2502f663ca6c8db6/junit-jupiter-api-5.10.2-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-api/5.10.2/fb55d6e2bce173f35fd28422e7975539621055ef/junit-jupiter-api-5.10.2.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-commons/1.10.2/513097c1d045c39db2fa42a54f830d4358936dc3/junit-platform-commons-1.10.2-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-commons/1.10.2/3197154a1f0c88da46c47a9ca27611ac7ec5d797/junit-platform-commons-1.10.2.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter/5.10.2/4e79ee610aff59d79b5f229252ded392b7d48fd1/junit-jupiter-5.10.2-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter/5.10.2/831c0b86ddc2ce38391c5b81ea662b0cfdc02cce/junit-jupiter-5.10.2.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.mockito/mockito-junit-jupiter/5.7.0/5d3de2c05dc223dbb76d5d57125e529fe3623fec/mockito-junit-jupiter-5.7.0-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.mockito/mockito-junit-jupiter/5.7.0/ac2d6a3431747a7986b8f4abef465f72bf3a21ae/mockito-junit-jupiter-5.7.0.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.mockito/mockito-core/5.7.0/1baa9a13c3471920b3319e4d0389a4745fd2ab08/mockito-core-5.7.0-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.mockito/mockito-core/5.7.0/a1c258331ab91d66863c983aff7136357e9de056/mockito-core-5.7.0.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.skyscreamer/jsonassert/1.5.1/56cfa73a7ab13fbb8d433570add90f087d40e243/jsonassert-1.5.1-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.skyscreamer/jsonassert/1.5.1/6d842d0faf4cf6725c509a5e5347d319ee0431c3/jsonassert-1.5.1.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-test/6.1.4/57f1ccb91ff6a29de8cf394cdd1e8cf603da0ba7/spring-test-6.1.4-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.springframework/spring-test/6.1.4/acef358552d3bb56a4da0894b8d2277de8ae39d9/spring-test-6.1.4.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.xmlunit/xmlunit-core/2.9.1/8ef88e77c158cdc17de55ad94e1e7e7972a91bd6/xmlunit-core-2.9.1-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.xmlunit/xmlunit-core/2.9.1/e5833662d9a1279a37da3ef6f62a1da29fcd68c4/xmlunit-core-2.9.1.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/jakarta.activation/jakarta.activation-api/2.1.2/d0310cf32e4c43f65b942c18cb2cc2bccfe2de37/jakarta.activation-api-2.1.2-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/jakarta.activation/jakarta.activation-api/2.1.2/640c0d5aff45dbff1e1a1bc09673ff3a02b1ba12/jakarta.activation-api-2.1.2.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/net.minidev/accessors-smart/2.5.0/596cf1b2ac57a905102db8fb648c4080529f347f/accessors-smart-2.5.0-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/net.minidev/accessors-smart/2.5.0/aca011492dfe9c26f4e0659028a4fe0970829dd8/accessors-smart-2.5.0.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy/1.14.12/887a4881279830607a6179560b17a44d62fc1997/byte-buddy-1.14.12-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy/1.14.12/6e37f743dc15a8d7a4feb3eb0025cbc612d5b9e1/byte-buddy-1.14.12.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.14.12/c9f6bb63cb973888eb2b2f139c6bfe5f3cc46ea3/byte-buddy-agent-1.14.12-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.14.12/be4984cb6fd1ef1d11f218a648889dfda44b8a15/byte-buddy-agent-1.14.12.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/com.vaadin.external.google/android-json/0.0.20131108.vaadin1/bf42d7e47a3228513b626dd7d37ac6f072aeca4f/android-json-0.0.20131108.vaadin1-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/com.vaadin.external.google/android-json/0.0.20131108.vaadin1/fa26d351fe62a6a17f5cda1287c1c6110dec413f/android-json-0.0.20131108.vaadin1.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.ow2.asm/asm/9.3/ce26e415ccafa10c6624a07bdb38d969110f568f/asm-9.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.ow2.asm/asm/9.3/8e6300ef51c1d801a7ed62d07cd221aca3a90640/asm-9.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.opentest4j/opentest4j/1.3.0/afb8ff23cffb021c56f333953aebfe6e8818568e/opentest4j-1.3.0-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.opentest4j/opentest4j/1.3.0/152ea56b3a72f655d4fd677fc0ef2596c3dd5e6e/opentest4j-1.3.0.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.apiguardian/apiguardian-api/1.1.2/e0787a997746ac32639e0bf3cb27af8dce8a3428/apiguardian-api-1.1.2-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.apiguardian/apiguardian-api/1.1.2/a231e0d844d2721b0fa1b238006d15c6ded6842a/apiguardian-api-1.1.2.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value=""/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-engine/5.10.2/624f71a8d76185f2ac8d234c686bbdab0bd28ae0/junit-jupiter-engine-5.10.2-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-engine/5.10.2/f1f8fe97bd58e85569205f071274d459c2c4f8cd/junit-jupiter-engine-5.10.2.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-engine/1.10.2/886c197f5fcfe9eaf0d1dde20aa1bd3abd653f44/junit-platform-engine-1.10.2-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-engine/1.10.2/d53bb4e0ce7f211a498705783440614bfaf0df2e/junit-platform-engine-1.10.2.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry sourcepath="/home/mario/.gradle/caches/modules-2/files-2.1/org.objenesis/objenesis/3.3/5fef34eeee6816b0ba2170755a8a9db7744990c3/objenesis-3.3-sources.jar" kind="lib" path="/home/mario/.gradle/caches/modules-2/files-2.1/org.objenesis/objenesis/3.3/1049c09f1de4331e8193e579448d0916d75b7631/objenesis-3.3.jar">
|
||||
<attributes>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
</classpath>
|
||||
BIN
.gradle/8.6/checksums/checksums.lock
Normal file
BIN
.gradle/8.6/checksums/checksums.lock
Normal file
Binary file not shown.
BIN
.gradle/8.6/checksums/md5-checksums.bin
Normal file
BIN
.gradle/8.6/checksums/md5-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/8.6/checksums/sha1-checksums.bin
Normal file
BIN
.gradle/8.6/checksums/sha1-checksums.bin
Normal file
Binary file not shown.
0
.gradle/8.6/dependencies-accessors/gc.properties
Normal file
0
.gradle/8.6/dependencies-accessors/gc.properties
Normal file
BIN
.gradle/8.6/executionHistory/executionHistory.bin
Normal file
BIN
.gradle/8.6/executionHistory/executionHistory.bin
Normal file
Binary file not shown.
BIN
.gradle/8.6/executionHistory/executionHistory.lock
Normal file
BIN
.gradle/8.6/executionHistory/executionHistory.lock
Normal file
Binary file not shown.
BIN
.gradle/8.6/fileChanges/last-build.bin
Normal file
BIN
.gradle/8.6/fileChanges/last-build.bin
Normal file
Binary file not shown.
BIN
.gradle/8.6/fileHashes/fileHashes.bin
Normal file
BIN
.gradle/8.6/fileHashes/fileHashes.bin
Normal file
Binary file not shown.
BIN
.gradle/8.6/fileHashes/fileHashes.lock
Normal file
BIN
.gradle/8.6/fileHashes/fileHashes.lock
Normal file
Binary file not shown.
BIN
.gradle/8.6/fileHashes/resourceHashesCache.bin
Normal file
BIN
.gradle/8.6/fileHashes/resourceHashesCache.bin
Normal file
Binary file not shown.
0
.gradle/8.6/gc.properties
Normal file
0
.gradle/8.6/gc.properties
Normal file
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
Binary file not shown.
2
.gradle/buildOutputCleanup/cache.properties
Normal file
2
.gradle/buildOutputCleanup/cache.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
#Sat Apr 18 12:25:04 CEST 2026
|
||||
gradle.version=8.6
|
||||
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
Binary file not shown.
BIN
.gradle/file-system.probe
Normal file
BIN
.gradle/file-system.probe
Normal file
Binary file not shown.
0
.gradle/vcs-1/gc.properties
Normal file
0
.gradle/vcs-1/gc.properties
Normal file
26
.project
Normal file
26
.project
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>linkster-backend</name>
|
||||
<comment></comment>
|
||||
<projects/>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments/>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments/>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
|
||||
<arguments/>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<linkedResources/>
|
||||
<filteredResources/>
|
||||
</projectDescription>
|
||||
13
.settings/org.eclipse.buildship.core.prefs
Normal file
13
.settings/org.eclipse.buildship.core.prefs
Normal file
@@ -0,0 +1,13 @@
|
||||
arguments=
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=false
|
||||
show.console.view=false
|
||||
show.executions.view=false
|
||||
8
.settings/org.eclipse.jdt.core.prefs
Normal file
8
.settings/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
#Sat Apr 18 12:29:07 CEST 2026
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
|
||||
org.eclipse.jdt.core.compiler.compliance=17
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=17
|
||||
2
.settings/org.springframework.ide.eclipse.prefs
Normal file
2
.settings/org.springframework.ide.eclipse.prefs
Normal file
@@ -0,0 +1,2 @@
|
||||
boot.validation.initialized=true
|
||||
eclipse.preferences.version=1
|
||||
4
Dockerfile
Normal file
4
Dockerfile
Normal file
@@ -0,0 +1,4 @@
|
||||
FROM eclipse-temurin:17-jre-jammy
|
||||
WORKDIR /app
|
||||
COPY build/libs/*.jar app.jar
|
||||
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||
2
bin/main/application.properties
Normal file
2
bin/main/application.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
server.port=8090
|
||||
spring.application.name=linkster-backend
|
||||
BIN
bin/main/de/oaa/linkster/LinksterApplication.class
Normal file
BIN
bin/main/de/oaa/linkster/LinksterApplication.class
Normal file
Binary file not shown.
BIN
bin/main/de/oaa/linkster/controller/ResolveController.class
Normal file
BIN
bin/main/de/oaa/linkster/controller/ResolveController.class
Normal file
Binary file not shown.
BIN
bin/main/de/oaa/linkster/filter/RequestLoggingFilter.class
Normal file
BIN
bin/main/de/oaa/linkster/filter/RequestLoggingFilter.class
Normal file
Binary file not shown.
BIN
bin/main/de/oaa/linkster/model/ResolveResponse.class
Normal file
BIN
bin/main/de/oaa/linkster/model/ResolveResponse.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
bin/main/de/oaa/linkster/service/PlaylistService.class
Normal file
BIN
bin/main/de/oaa/linkster/service/PlaylistService.class
Normal file
Binary file not shown.
35
bin/main/logback-spring.xml
Normal file
35
bin/main/logback-spring.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<configuration>
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE_ERRORS" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>logs/errors.log</file>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>WARN</level>
|
||||
</filter>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>logs/errors.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="de.oaa.linkster" level="INFO"/>
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE_ERRORS"/>
|
||||
</root>
|
||||
|
||||
<logger name="de.oaa.linkster" level="INFO" additivity="false">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE_ERRORS"/>
|
||||
</logger>
|
||||
|
||||
</configuration>
|
||||
256
bin/main/playlists/all.json
Normal file
256
bin/main/playlists/all.json
Normal file
@@ -0,0 +1,256 @@
|
||||
[
|
||||
{
|
||||
"id": "hitster-bingo-deutschland",
|
||||
"name": "Hitster Bingo Deutschland",
|
||||
"matcher": "/de/aaaa0019/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-ca",
|
||||
"name": "Hitster Canada",
|
||||
"matcher": "/ca/aaad0001/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-ca-franco",
|
||||
"name": "Hitster Canada (Franco)",
|
||||
"matcher": "/ca/aaad0002/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-ca-guilty-pleasures",
|
||||
"name": "Hitster Guilty Pleasures (CA)",
|
||||
"matcher": "/ca/aaad0003/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de",
|
||||
"name": "Hitster Deutsch",
|
||||
"matcher": "/de/(\\d{5})$/",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
},
|
||||
"available": true
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-bayern-1-expansion",
|
||||
"name": "Hitster Bayern 1 Expansion (DE)",
|
||||
"matcher": "/de/aaaa0025/(\\d{5})$/",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "no",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
},
|
||||
"available": true
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-celebration",
|
||||
"name": "Hitster Celebration (DE)",
|
||||
"matcher": "/de/aaaa0040/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-guilty-pleasures",
|
||||
"name": "Hitster Guilty Pleasures (DE)",
|
||||
"matcher": "/de/aaaa0015/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-rock",
|
||||
"name": "Hitster Rock (DE)",
|
||||
"matcher": "/de/aaaa0039/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-schlager-party",
|
||||
"name": "Hitster Schlager Party (DE)",
|
||||
"matcher": "/de/aaaa0007/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-soundtracks-expansion",
|
||||
"name": "Hitster Soundtracks Expansion (DE)",
|
||||
"matcher": "/de/aaaa0026/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-summer-party",
|
||||
"name": "Hitster Summer Party (DE)",
|
||||
"matcher": "/de/aaaa0012/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-guilty-pleasures-nor",
|
||||
"name": "Hitster Guilty Pleasures (NOR)",
|
||||
"matcher": "/dk/aaaa0024/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-it",
|
||||
"name": "Hitster Italia",
|
||||
"matcher": "/it/aaac0001/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-uk",
|
||||
"name": "Hitster UK",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "no",
|
||||
"youtubeMusic": "no"
|
||||
},
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"id": "hitster-usa",
|
||||
"name": "Hitster USA",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "no",
|
||||
"youtubeMusic": "no"
|
||||
},
|
||||
"available": false
|
||||
}
|
||||
]
|
||||
6993
bin/main/playlists/hitster-bingo-deutschland.json
Normal file
6993
bin/main/playlists/hitster-bingo-deutschland.json
Normal file
File diff suppressed because it is too large
Load Diff
9450
bin/main/playlists/hitster-ca-franco.json
Normal file
9450
bin/main/playlists/hitster-ca-franco.json
Normal file
File diff suppressed because it is too large
Load Diff
9566
bin/main/playlists/hitster-ca-guilty-pleasures.json
Normal file
9566
bin/main/playlists/hitster-ca-guilty-pleasures.json
Normal file
File diff suppressed because it is too large
Load Diff
9548
bin/main/playlists/hitster-ca.json
Normal file
9548
bin/main/playlists/hitster-ca.json
Normal file
File diff suppressed because it is too large
Load Diff
4776
bin/main/playlists/hitster-de-bayern-1-expansion.json
Normal file
4776
bin/main/playlists/hitster-de-bayern-1-expansion.json
Normal file
File diff suppressed because it is too large
Load Diff
9538
bin/main/playlists/hitster-de-celebration.json
Normal file
9538
bin/main/playlists/hitster-de-celebration.json
Normal file
File diff suppressed because it is too large
Load Diff
9552
bin/main/playlists/hitster-de-guilty-pleasures.json
Normal file
9552
bin/main/playlists/hitster-de-guilty-pleasures.json
Normal file
File diff suppressed because it is too large
Load Diff
9566
bin/main/playlists/hitster-de-rock.json
Normal file
9566
bin/main/playlists/hitster-de-rock.json
Normal file
File diff suppressed because it is too large
Load Diff
9462
bin/main/playlists/hitster-de-schlager-party.json
Normal file
9462
bin/main/playlists/hitster-de-schlager-party.json
Normal file
File diff suppressed because it is too large
Load Diff
4750
bin/main/playlists/hitster-de-soundtracks-expansion.json
Normal file
4750
bin/main/playlists/hitster-de-soundtracks-expansion.json
Normal file
File diff suppressed because it is too large
Load Diff
9532
bin/main/playlists/hitster-de-summer-party.json
Normal file
9532
bin/main/playlists/hitster-de-summer-party.json
Normal file
File diff suppressed because it is too large
Load Diff
9566
bin/main/playlists/hitster-de.json
Normal file
9566
bin/main/playlists/hitster-de.json
Normal file
File diff suppressed because it is too large
Load Diff
9566
bin/main/playlists/hitster-guilty-pleasures-nor.json
Normal file
9566
bin/main/playlists/hitster-guilty-pleasures-nor.json
Normal file
File diff suppressed because it is too large
Load Diff
9550
bin/main/playlists/hitster-it.json
Normal file
9550
bin/main/playlists/hitster-it.json
Normal file
File diff suppressed because it is too large
Load Diff
9541
bin/main/playlists/hitster-uk.json
Normal file
9541
bin/main/playlists/hitster-uk.json
Normal file
File diff suppressed because it is too large
Load Diff
9547
bin/main/playlists/hitster-usa.json
Normal file
9547
bin/main/playlists/hitster-usa.json
Normal file
File diff suppressed because it is too large
Load Diff
359
bin/main/static/index.html
Normal file
359
bin/main/static/index.html
Normal file
@@ -0,0 +1,359 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Linkster</title>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
background: #0f1117;
|
||||
color: #e2e8f0;
|
||||
line-height: 1.6;
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
|
||||
.container { max-width: 780px; margin: 0 auto; }
|
||||
|
||||
header { margin-bottom: 2.5rem; }
|
||||
header h1 { font-size: 2rem; font-weight: 700; color: #f8fafc; }
|
||||
header p { color: #94a3b8; margin-top: .4rem; }
|
||||
|
||||
h2 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: #f8fafc;
|
||||
margin: 2rem 0 .75rem;
|
||||
padding-bottom: .4rem;
|
||||
border-bottom: 1px solid #1e293b;
|
||||
}
|
||||
|
||||
.endpoint {
|
||||
background: #1e293b;
|
||||
border: 1px solid #334155;
|
||||
border-radius: .5rem;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.endpoint .method {
|
||||
display: inline-block;
|
||||
background: #2563eb;
|
||||
color: #fff;
|
||||
font-size: .75rem;
|
||||
font-weight: 700;
|
||||
padding: .15rem .5rem;
|
||||
border-radius: .25rem;
|
||||
margin-right: .6rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.endpoint .path {
|
||||
font-family: "SFMono-Regular", Consolas, monospace;
|
||||
font-size: .95rem;
|
||||
color: #7dd3fc;
|
||||
}
|
||||
.endpoint .desc { color: #94a3b8; margin-top: .4rem; font-size: .9rem; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: .9rem;
|
||||
}
|
||||
th {
|
||||
text-align: left;
|
||||
padding: .5rem .75rem;
|
||||
background: #1e293b;
|
||||
color: #94a3b8;
|
||||
font-weight: 600;
|
||||
font-size: .8rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .05em;
|
||||
}
|
||||
td {
|
||||
padding: .5rem .75rem;
|
||||
border-top: 1px solid #1e293b;
|
||||
}
|
||||
td code {
|
||||
font-family: "SFMono-Regular", Consolas, monospace;
|
||||
background: #1e293b;
|
||||
padding: .1rem .35rem;
|
||||
border-radius: .25rem;
|
||||
font-size: .85rem;
|
||||
color: #7dd3fc;
|
||||
}
|
||||
tr:hover td { background: #0f1e30; }
|
||||
|
||||
pre {
|
||||
background: #1e293b;
|
||||
border: 1px solid #334155;
|
||||
border-radius: .5rem;
|
||||
padding: 1rem 1.25rem;
|
||||
overflow-x: auto;
|
||||
font-family: "SFMono-Regular", Consolas, monospace;
|
||||
font-size: .85rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.key { color: #7dd3fc; }
|
||||
.str { color: #86efac; }
|
||||
.bool { color: #f472b6; }
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
font-size: .7rem;
|
||||
padding: .1rem .4rem;
|
||||
border-radius: .2rem;
|
||||
font-weight: 600;
|
||||
margin-left: .3rem;
|
||||
}
|
||||
.badge-full { background: #14532d; color: #86efac; }
|
||||
.badge-no { background: #450a0a; color: #fca5a5; }
|
||||
|
||||
.playlist-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: .5rem;
|
||||
}
|
||||
.playlist-item {
|
||||
background: #1e293b;
|
||||
border: 1px solid #334155;
|
||||
border-radius: .375rem;
|
||||
padding: .5rem .75rem;
|
||||
font-size: .85rem;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 3rem;
|
||||
padding-top: 1rem;
|
||||
border-top: 1px solid #1e293b;
|
||||
color: #475569;
|
||||
font-size: .8rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: .5rem;
|
||||
}
|
||||
footer a { color: #64748b; text-decoration: none; }
|
||||
footer a:hover { color: #94a3b8; }
|
||||
|
||||
.download-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: .5rem;
|
||||
margin-top: .75rem;
|
||||
padding: .5rem 1rem;
|
||||
background: #16a34a;
|
||||
color: #fff;
|
||||
font-size: .85rem;
|
||||
font-weight: 600;
|
||||
border-radius: .375rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
.download-btn:hover { background: #15803d; }
|
||||
|
||||
.legal {
|
||||
margin-top: 4rem;
|
||||
padding-top: 2rem;
|
||||
border-top: 2px solid #1e293b;
|
||||
}
|
||||
.legal h2 {
|
||||
font-size: 1.3rem;
|
||||
margin-top: 2.5rem;
|
||||
}
|
||||
.legal h3 {
|
||||
font-size: .95rem;
|
||||
font-weight: 600;
|
||||
color: #cbd5e1;
|
||||
margin: 1.25rem 0 .4rem;
|
||||
}
|
||||
.legal p {
|
||||
color: #94a3b8;
|
||||
font-size: .9rem;
|
||||
margin-bottom: .6rem;
|
||||
}
|
||||
.legal address {
|
||||
font-style: normal;
|
||||
color: #94a3b8;
|
||||
font-size: .9rem;
|
||||
line-height: 1.8;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<header>
|
||||
<h1>Linkster App</h1>
|
||||
<p style="margin-top:.75rem">Löst die QR-Code aus einem bekannten Spiel auf und ermöglicht den Aufruf anderer Streaming Dienste als Spotify.</p>
|
||||
<a class="download-btn" href="/linkster.apk" download="linkster-1.0.apk">
|
||||
↓ Android App herunterladen (v1.0)
|
||||
</a>
|
||||
<p>
|
||||
<h2>Installation</h2>
|
||||
<h3>1. Die APK-Datei finden</h3>
|
||||
<p>Zuerst musst du die Datei auf deinem Gerät finden. Meistens landet sie im Ordner Downloads.</p>
|
||||
<p>Öffne eine Dateimanager-App (oft heißt sie "Eigene Dateien", "Files" oder "Dateien").</p>
|
||||
<p>Navigiere zum Ordner Downloads und tippe die APK-Datei an.</p>
|
||||
<h3>2. Installation aus unbekannten Quellen erlauben</h3>
|
||||
<p>Wenn du die Datei das erste Mal antippst, erscheint normalerweise eine Sicherheitswarnung.</p>
|
||||
<p>Tippe in dem Pop-up-Fenster auf Einstellungen.</p>
|
||||
<p>Du wirst nun zu einem Menü weitergeleitet ("Unbekannte Apps installieren"). Dort musst du den Schalter bei der App aktivieren, mit der du die APK öffnen willst (z. B. Chrome oder dein Dateimanager).</p>
|
||||
<p>Gehe danach zurück zur Datei.</p>
|
||||
<h3>3. Installation durchführen</h3>
|
||||
<p>Tippe die Datei erneut an.</p>
|
||||
<p>Es erscheint die Frage: "Möchtest du diese App installieren?". Bestätige dies mit Installieren.</p>
|
||||
<p>Nach kurzem Warten ist die App bereit und du kannst auf Öffnen tippen.</p>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<h1>Linkster API</h1>
|
||||
<h2>Endpunkte</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method">GET</span>
|
||||
<span class="path">/api/resolve?url={url}</span>
|
||||
<div class="desc">Löst einen Streaming-Link auf und gibt Titel, Künstler und verfügbare Provider-Links zurück.</div>
|
||||
</div>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method">GET</span>
|
||||
<span class="path">/api/health</span>
|
||||
<div class="desc">Gibt <code>"ok"</code> zurück, wenn der Server läuft.</div>
|
||||
</div>
|
||||
|
||||
<h2>Parameter</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Parameter</th><th>Typ</th><th>Beschreibung</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>url</code></td>
|
||||
<td>string</td>
|
||||
<td>Die vollständige URL vom Hitster-QR-Code (z.B. Apple Music Link)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>Antwort (gefunden)</h2>
|
||||
<pre><span class="key">"found"</span>: <span class="bool">true</span>,
|
||||
<span class="key">"title"</span>: <span class="str">"Song-Titel"</span>,
|
||||
<span class="key">"artist"</span>: <span class="str">"Künstlername"</span>,
|
||||
<span class="key">"playlist"</span>: <span class="str">"Hitster Deutsch"</span>,
|
||||
<span class="key">"providers"</span>: {
|
||||
<span class="key">"spotify"</span>: <span class="str">"https://open.spotify.com/track/..."</span>,
|
||||
<span class="key">"deezer"</span>: <span class="str">"https://www.deezer.com/track/..."</span>,
|
||||
<span class="key">"youtube"</span>: <span class="str">"https://www.youtube.com/watch?v=..."</span>,
|
||||
<span class="key">"youtubeMusic"</span>: <span class="str">"https://music.youtube.com/watch?v=..."</span>,
|
||||
<span class="key">"appleMusic"</span>: <span class="str">"https://music.apple.com/..."</span>,
|
||||
<span class="key">"amazonMusic"</span>: <span class="str">"https://music.amazon.com/..."</span>,
|
||||
<span class="key">"tidal"</span>: <span class="str">"https://tidal.com/track/..."</span>
|
||||
}</pre>
|
||||
|
||||
<h2>Antwort (nicht gefunden)</h2>
|
||||
<pre><span class="key">"found"</span>: <span class="bool">false</span></pre>
|
||||
|
||||
<h2>Unterstützte Playlists</h2>
|
||||
<div class="playlist-grid">
|
||||
<div class="playlist-item">Hitster Deutsch</div>
|
||||
<div class="playlist-item">Hitster Bingo Deutschland</div>
|
||||
<div class="playlist-item">Hitster Bayern 1 Expansion (DE)</div>
|
||||
<div class="playlist-item">Hitster Celebration (DE)</div>
|
||||
<div class="playlist-item">Hitster Guilty Pleasures (DE)</div>
|
||||
<div class="playlist-item">Hitster Rock (DE)</div>
|
||||
<div class="playlist-item">Hitster Schlager Party (DE)</div>
|
||||
<div class="playlist-item">Hitster Soundtracks Expansion (DE)</div>
|
||||
<div class="playlist-item">Hitster Summer Party (DE)</div>
|
||||
<div class="playlist-item">Hitster Canada</div>
|
||||
<div class="playlist-item">Hitster Canada (Franco)</div>
|
||||
<div class="playlist-item">Hitster Guilty Pleasures (CA)</div>
|
||||
<div class="playlist-item">Hitster Guilty Pleasures (NOR)</div>
|
||||
<div class="playlist-item">Hitster Italia</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<span>Linkster — linkster.langhei.de</span>
|
||||
<span>
|
||||
<a href="#impressum">Impressum</a>
|
||||
 · 
|
||||
<a href="#datenschutz">Datenschutz</a>
|
||||
</span>
|
||||
</footer>
|
||||
|
||||
<div class="legal">
|
||||
|
||||
<h2 id="impressum">Impressum</h2>
|
||||
|
||||
<h3>Angaben gemäß § 5 TMG</h3>
|
||||
<address>
|
||||
Mario Störmer<br>
|
||||
Langheide 14<br>
|
||||
24354 Rieseby<br>
|
||||
Deutschland
|
||||
</address>
|
||||
|
||||
<h3>Hinweis</h3>
|
||||
<p>
|
||||
Dieses Angebot ist ein privates, nicht-kommerzielles Hobbyprojekt.
|
||||
Es werden keine wirtschaftlichen Interessen verfolgt und kein Entgelt erhoben.
|
||||
</p>
|
||||
|
||||
<h2 id="datenschutz">Datenschutzerklärung</h2>
|
||||
|
||||
<h3>Verantwortlicher</h3>
|
||||
<address>
|
||||
Mario Störmer<br>
|
||||
Langheide 14<br>
|
||||
24354 Rieseby<br>
|
||||
Deutschland
|
||||
</address>
|
||||
|
||||
<h3>Welche Daten werden verarbeitet?</h3>
|
||||
<p>
|
||||
Beim Aufruf dieser Seite und der API werden technisch bedingt folgende Daten
|
||||
kurzfristig im Server-Log gespeichert:
|
||||
</p>
|
||||
<p>
|
||||
IP-Adresse des anfragenden Geräts, aufgerufene URL, Zeitpunkt der Anfrage sowie
|
||||
HTTP-Statuscode. Diese Daten sind für den stabilen Betrieb des Dienstes notwendig
|
||||
und werden nicht an Dritte weitergegeben.
|
||||
</p>
|
||||
|
||||
<h3>Zweck der Verarbeitung</h3>
|
||||
<p>
|
||||
Die Daten werden ausschließlich zur Fehleranalyse und Sicherstellung des Betriebs
|
||||
verwendet. Eine Auswertung zu Analyse-, Tracking- oder Werbezwecken findet nicht statt.
|
||||
</p>
|
||||
|
||||
<h3>Speicherdauer</h3>
|
||||
<p>
|
||||
Server-Logs werden automatisch nach 30 Tagen gelöscht. Es erfolgt keine
|
||||
dauerhafte Speicherung personenbezogener Daten.
|
||||
</p>
|
||||
|
||||
<h3>Cookies & Tracking</h3>
|
||||
<p>
|
||||
Diese Website verwendet keine Cookies, keine Analyse-Tools und kein Tracking
|
||||
jeglicher Art.
|
||||
</p>
|
||||
|
||||
<h3>Weitergabe an Dritte</h3>
|
||||
<p>
|
||||
Es findet keine Weitergabe von Daten an Dritte statt. Der Dienst ist
|
||||
ausschließlich für den privaten Gebrauch bestimmt.
|
||||
</p>
|
||||
|
||||
<h3>Rechte betroffener Personen</h3>
|
||||
<p>
|
||||
Gemäß DSGVO stehen Ihnen das Recht auf Auskunft, Berichtigung, Löschung und
|
||||
Einschränkung der Verarbeitung zu. Anfragen können per Post an die oben genannte
|
||||
Adresse gerichtet werden.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
26
build.gradle
Normal file
26
build.gradle
Normal file
@@ -0,0 +1,26 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '3.2.3'
|
||||
id 'io.spring.dependency-management' version '1.1.4'
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'de.oaa.linkster'
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
|
||||
java {
|
||||
sourceCompatibility = '17'
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
}
|
||||
|
||||
bootBuildImage {
|
||||
imageName = 'linkster-backend:latest'
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/libs/linkster-backend-0.0.1-SNAPSHOT.jar
Normal file
BIN
build/libs/linkster-backend-0.0.1-SNAPSHOT.jar
Normal file
Binary file not shown.
1
build/resolvedMainClassName
Normal file
1
build/resolvedMainClassName
Normal file
@@ -0,0 +1 @@
|
||||
de.oaa.linkster.LinksterApplication
|
||||
2
build/resources/main/application.properties
Normal file
2
build/resources/main/application.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
server.port=8090
|
||||
spring.application.name=linkster-backend
|
||||
35
build/resources/main/logback-spring.xml
Normal file
35
build/resources/main/logback-spring.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<configuration>
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE_ERRORS" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>logs/errors.log</file>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>WARN</level>
|
||||
</filter>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>logs/errors.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="de.oaa.linkster" level="INFO"/>
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE_ERRORS"/>
|
||||
</root>
|
||||
|
||||
<logger name="de.oaa.linkster" level="INFO" additivity="false">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE_ERRORS"/>
|
||||
</logger>
|
||||
|
||||
</configuration>
|
||||
256
build/resources/main/playlists/all.json
Normal file
256
build/resources/main/playlists/all.json
Normal file
@@ -0,0 +1,256 @@
|
||||
[
|
||||
{
|
||||
"id": "hitster-bingo-deutschland",
|
||||
"name": "Hitster Bingo Deutschland",
|
||||
"matcher": "/de/aaaa0019/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-ca",
|
||||
"name": "Hitster Canada",
|
||||
"matcher": "/ca/aaad0001/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-ca-franco",
|
||||
"name": "Hitster Canada (Franco)",
|
||||
"matcher": "/ca/aaad0002/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-ca-guilty-pleasures",
|
||||
"name": "Hitster Guilty Pleasures (CA)",
|
||||
"matcher": "/ca/aaad0003/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de",
|
||||
"name": "Hitster Deutsch",
|
||||
"matcher": "/de/(\\d{5})$/",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
},
|
||||
"available": true
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-bayern-1-expansion",
|
||||
"name": "Hitster Bayern 1 Expansion (DE)",
|
||||
"matcher": "/de/aaaa0025/(\\d{5})$/",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "no",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
},
|
||||
"available": true
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-celebration",
|
||||
"name": "Hitster Celebration (DE)",
|
||||
"matcher": "/de/aaaa0040/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-guilty-pleasures",
|
||||
"name": "Hitster Guilty Pleasures (DE)",
|
||||
"matcher": "/de/aaaa0015/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-rock",
|
||||
"name": "Hitster Rock (DE)",
|
||||
"matcher": "/de/aaaa0039/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-schlager-party",
|
||||
"name": "Hitster Schlager Party (DE)",
|
||||
"matcher": "/de/aaaa0007/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-soundtracks-expansion",
|
||||
"name": "Hitster Soundtracks Expansion (DE)",
|
||||
"matcher": "/de/aaaa0026/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-summer-party",
|
||||
"name": "Hitster Summer Party (DE)",
|
||||
"matcher": "/de/aaaa0012/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-guilty-pleasures-nor",
|
||||
"name": "Hitster Guilty Pleasures (NOR)",
|
||||
"matcher": "/dk/aaaa0024/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-it",
|
||||
"name": "Hitster Italia",
|
||||
"matcher": "/it/aaac0001/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-uk",
|
||||
"name": "Hitster UK",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "no",
|
||||
"youtubeMusic": "no"
|
||||
},
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"id": "hitster-usa",
|
||||
"name": "Hitster USA",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "no",
|
||||
"youtubeMusic": "no"
|
||||
},
|
||||
"available": false
|
||||
}
|
||||
]
|
||||
6993
build/resources/main/playlists/hitster-bingo-deutschland.json
Normal file
6993
build/resources/main/playlists/hitster-bingo-deutschland.json
Normal file
File diff suppressed because it is too large
Load Diff
9450
build/resources/main/playlists/hitster-ca-franco.json
Normal file
9450
build/resources/main/playlists/hitster-ca-franco.json
Normal file
File diff suppressed because it is too large
Load Diff
9566
build/resources/main/playlists/hitster-ca-guilty-pleasures.json
Normal file
9566
build/resources/main/playlists/hitster-ca-guilty-pleasures.json
Normal file
File diff suppressed because it is too large
Load Diff
9548
build/resources/main/playlists/hitster-ca.json
Normal file
9548
build/resources/main/playlists/hitster-ca.json
Normal file
File diff suppressed because it is too large
Load Diff
4776
build/resources/main/playlists/hitster-de-bayern-1-expansion.json
Normal file
4776
build/resources/main/playlists/hitster-de-bayern-1-expansion.json
Normal file
File diff suppressed because it is too large
Load Diff
9538
build/resources/main/playlists/hitster-de-celebration.json
Normal file
9538
build/resources/main/playlists/hitster-de-celebration.json
Normal file
File diff suppressed because it is too large
Load Diff
9552
build/resources/main/playlists/hitster-de-guilty-pleasures.json
Normal file
9552
build/resources/main/playlists/hitster-de-guilty-pleasures.json
Normal file
File diff suppressed because it is too large
Load Diff
9566
build/resources/main/playlists/hitster-de-rock.json
Normal file
9566
build/resources/main/playlists/hitster-de-rock.json
Normal file
File diff suppressed because it is too large
Load Diff
9462
build/resources/main/playlists/hitster-de-schlager-party.json
Normal file
9462
build/resources/main/playlists/hitster-de-schlager-party.json
Normal file
File diff suppressed because it is too large
Load Diff
4750
build/resources/main/playlists/hitster-de-soundtracks-expansion.json
Normal file
4750
build/resources/main/playlists/hitster-de-soundtracks-expansion.json
Normal file
File diff suppressed because it is too large
Load Diff
9532
build/resources/main/playlists/hitster-de-summer-party.json
Normal file
9532
build/resources/main/playlists/hitster-de-summer-party.json
Normal file
File diff suppressed because it is too large
Load Diff
9566
build/resources/main/playlists/hitster-de.json
Normal file
9566
build/resources/main/playlists/hitster-de.json
Normal file
File diff suppressed because it is too large
Load Diff
9566
build/resources/main/playlists/hitster-guilty-pleasures-nor.json
Normal file
9566
build/resources/main/playlists/hitster-guilty-pleasures-nor.json
Normal file
File diff suppressed because it is too large
Load Diff
9550
build/resources/main/playlists/hitster-it.json
Normal file
9550
build/resources/main/playlists/hitster-it.json
Normal file
File diff suppressed because it is too large
Load Diff
9541
build/resources/main/playlists/hitster-uk.json
Normal file
9541
build/resources/main/playlists/hitster-uk.json
Normal file
File diff suppressed because it is too large
Load Diff
9547
build/resources/main/playlists/hitster-usa.json
Normal file
9547
build/resources/main/playlists/hitster-usa.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
build/resources/main/static/favicon.png
Normal file
BIN
build/resources/main/static/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 366 KiB |
361
build/resources/main/static/index.html
Normal file
361
build/resources/main/static/index.html
Normal file
@@ -0,0 +1,361 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Linkster</title>
|
||||
<link rel="icon" type="image/png" href="/favicon.png">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
background: #0f1117;
|
||||
color: #e2e8f0;
|
||||
line-height: 1.6;
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
|
||||
.container { max-width: 780px; margin: 0 auto; }
|
||||
|
||||
header { margin-bottom: 2.5rem; }
|
||||
header h1 { font-size: 2rem; font-weight: 700; color: #f8fafc; }
|
||||
header p { color: #94a3b8; margin-top: .4rem; }
|
||||
|
||||
h2 {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: #f8fafc;
|
||||
margin: 2rem 0 .75rem;
|
||||
padding-bottom: .4rem;
|
||||
border-bottom: 1px solid #1e293b;
|
||||
}
|
||||
|
||||
.endpoint {
|
||||
background: #1e293b;
|
||||
border: 1px solid #334155;
|
||||
border-radius: .5rem;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.endpoint .method {
|
||||
display: inline-block;
|
||||
background: #2563eb;
|
||||
color: #fff;
|
||||
font-size: .75rem;
|
||||
font-weight: 700;
|
||||
padding: .15rem .5rem;
|
||||
border-radius: .25rem;
|
||||
margin-right: .6rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.endpoint .path {
|
||||
font-family: "SFMono-Regular", Consolas, monospace;
|
||||
font-size: .95rem;
|
||||
color: #7dd3fc;
|
||||
}
|
||||
.endpoint .desc { color: #94a3b8; margin-top: .4rem; font-size: .9rem; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: .9rem;
|
||||
}
|
||||
th {
|
||||
text-align: left;
|
||||
padding: .5rem .75rem;
|
||||
background: #1e293b;
|
||||
color: #94a3b8;
|
||||
font-weight: 600;
|
||||
font-size: .8rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .05em;
|
||||
}
|
||||
td {
|
||||
padding: .5rem .75rem;
|
||||
border-top: 1px solid #1e293b;
|
||||
}
|
||||
td code {
|
||||
font-family: "SFMono-Regular", Consolas, monospace;
|
||||
background: #1e293b;
|
||||
padding: .1rem .35rem;
|
||||
border-radius: .25rem;
|
||||
font-size: .85rem;
|
||||
color: #7dd3fc;
|
||||
}
|
||||
tr:hover td { background: #0f1e30; }
|
||||
|
||||
pre {
|
||||
background: #1e293b;
|
||||
border: 1px solid #334155;
|
||||
border-radius: .5rem;
|
||||
padding: 1rem 1.25rem;
|
||||
overflow-x: auto;
|
||||
font-family: "SFMono-Regular", Consolas, monospace;
|
||||
font-size: .85rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.key { color: #7dd3fc; }
|
||||
.str { color: #86efac; }
|
||||
.bool { color: #f472b6; }
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
font-size: .7rem;
|
||||
padding: .1rem .4rem;
|
||||
border-radius: .2rem;
|
||||
font-weight: 600;
|
||||
margin-left: .3rem;
|
||||
}
|
||||
.badge-full { background: #14532d; color: #86efac; }
|
||||
.badge-no { background: #450a0a; color: #fca5a5; }
|
||||
|
||||
.playlist-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: .5rem;
|
||||
}
|
||||
.playlist-item {
|
||||
background: #1e293b;
|
||||
border: 1px solid #334155;
|
||||
border-radius: .375rem;
|
||||
padding: .5rem .75rem;
|
||||
font-size: .85rem;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 3rem;
|
||||
padding-top: 1rem;
|
||||
border-top: 1px solid #1e293b;
|
||||
color: #475569;
|
||||
font-size: .8rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: .5rem;
|
||||
}
|
||||
footer a { color: #64748b; text-decoration: none; }
|
||||
footer a:hover { color: #94a3b8; }
|
||||
|
||||
.download-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: .5rem;
|
||||
margin-top: .75rem;
|
||||
padding: .5rem 1rem;
|
||||
background: #16a34a;
|
||||
color: #fff;
|
||||
font-size: .85rem;
|
||||
font-weight: 600;
|
||||
border-radius: .375rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
.download-btn:hover { background: #15803d; }
|
||||
|
||||
.legal {
|
||||
margin-top: 4rem;
|
||||
padding-top: 2rem;
|
||||
border-top: 2px solid #1e293b;
|
||||
}
|
||||
.legal h2 {
|
||||
font-size: 1.3rem;
|
||||
margin-top: 2.5rem;
|
||||
}
|
||||
.legal h3 {
|
||||
font-size: .95rem;
|
||||
font-weight: 600;
|
||||
color: #cbd5e1;
|
||||
margin: 1.25rem 0 .4rem;
|
||||
}
|
||||
.legal p {
|
||||
color: #94a3b8;
|
||||
font-size: .9rem;
|
||||
margin-bottom: .6rem;
|
||||
}
|
||||
.legal address {
|
||||
font-style: normal;
|
||||
color: #94a3b8;
|
||||
font-size: .9rem;
|
||||
line-height: 1.8;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<header>
|
||||
<img src="/favicon.png" alt="Linkster Logo" style="width:80px;height:80px;border-radius:.75rem;margin-bottom:.75rem;display:block;">
|
||||
<h1>Linkster App</h1>
|
||||
<p style="margin-top:.75rem">Löst die QR-Code aus einem bekannten Spiel auf und ermöglicht den Aufruf anderer Streaming Dienste als Spotify.</p>
|
||||
<a class="download-btn" href="/linkster.apk" download="linkster-1.0.apk">
|
||||
↓ Android App herunterladen (v1.0)
|
||||
</a>
|
||||
<p>
|
||||
<h2>Installation</h2>
|
||||
<h3>1. Die APK-Datei finden</h3>
|
||||
<p>Zuerst musst du die Datei auf deinem Gerät finden. Meistens landet sie im Ordner Downloads.</p>
|
||||
<p>Öffne eine Dateimanager-App (oft heißt sie "Eigene Dateien", "Files" oder "Dateien").</p>
|
||||
<p>Navigiere zum Ordner Downloads und tippe die APK-Datei an.</p>
|
||||
<h3>2. Installation aus unbekannten Quellen erlauben</h3>
|
||||
<p>Wenn du die Datei das erste Mal antippst, erscheint normalerweise eine Sicherheitswarnung.</p>
|
||||
<p>Tippe in dem Pop-up-Fenster auf Einstellungen.</p>
|
||||
<p>Du wirst nun zu einem Menü weitergeleitet ("Unbekannte Apps installieren"). Dort musst du den Schalter bei der App aktivieren, mit der du die APK öffnen willst (z. B. Chrome oder dein Dateimanager).</p>
|
||||
<p>Gehe danach zurück zur Datei.</p>
|
||||
<h3>3. Installation durchführen</h3>
|
||||
<p>Tippe die Datei erneut an.</p>
|
||||
<p>Es erscheint die Frage: "Möchtest du diese App installieren?". Bestätige dies mit Installieren.</p>
|
||||
<p>Nach kurzem Warten ist die App bereit und du kannst auf Öffnen tippen.</p>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<h1>Linkster API</h1>
|
||||
<h2>Endpunkte</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method">GET</span>
|
||||
<span class="path">/api/resolve?url={url}</span>
|
||||
<div class="desc">Löst einen Streaming-Link auf und gibt Titel, Künstler und verfügbare Provider-Links zurück.</div>
|
||||
</div>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method">GET</span>
|
||||
<span class="path">/api/health</span>
|
||||
<div class="desc">Gibt <code>"ok"</code> zurück, wenn der Server läuft.</div>
|
||||
</div>
|
||||
|
||||
<h2>Parameter</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Parameter</th><th>Typ</th><th>Beschreibung</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>url</code></td>
|
||||
<td>string</td>
|
||||
<td>Die vollständige URL vom Hitster-QR-Code (z.B. Apple Music Link)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>Antwort (gefunden)</h2>
|
||||
<pre><span class="key">"found"</span>: <span class="bool">true</span>,
|
||||
<span class="key">"title"</span>: <span class="str">"Song-Titel"</span>,
|
||||
<span class="key">"artist"</span>: <span class="str">"Künstlername"</span>,
|
||||
<span class="key">"playlist"</span>: <span class="str">"Hitster Deutsch"</span>,
|
||||
<span class="key">"providers"</span>: {
|
||||
<span class="key">"spotify"</span>: <span class="str">"https://open.spotify.com/track/..."</span>,
|
||||
<span class="key">"deezer"</span>: <span class="str">"https://www.deezer.com/track/..."</span>,
|
||||
<span class="key">"youtube"</span>: <span class="str">"https://www.youtube.com/watch?v=..."</span>,
|
||||
<span class="key">"youtubeMusic"</span>: <span class="str">"https://music.youtube.com/watch?v=..."</span>,
|
||||
<span class="key">"appleMusic"</span>: <span class="str">"https://music.apple.com/..."</span>,
|
||||
<span class="key">"amazonMusic"</span>: <span class="str">"https://music.amazon.com/..."</span>,
|
||||
<span class="key">"tidal"</span>: <span class="str">"https://tidal.com/track/..."</span>
|
||||
}</pre>
|
||||
|
||||
<h2>Antwort (nicht gefunden)</h2>
|
||||
<pre><span class="key">"found"</span>: <span class="bool">false</span></pre>
|
||||
|
||||
<h2>Unterstützte Playlists</h2>
|
||||
<div class="playlist-grid">
|
||||
<div class="playlist-item">Hitster Deutsch</div>
|
||||
<div class="playlist-item">Hitster Bingo Deutschland</div>
|
||||
<div class="playlist-item">Hitster Bayern 1 Expansion (DE)</div>
|
||||
<div class="playlist-item">Hitster Celebration (DE)</div>
|
||||
<div class="playlist-item">Hitster Guilty Pleasures (DE)</div>
|
||||
<div class="playlist-item">Hitster Rock (DE)</div>
|
||||
<div class="playlist-item">Hitster Schlager Party (DE)</div>
|
||||
<div class="playlist-item">Hitster Soundtracks Expansion (DE)</div>
|
||||
<div class="playlist-item">Hitster Summer Party (DE)</div>
|
||||
<div class="playlist-item">Hitster Canada</div>
|
||||
<div class="playlist-item">Hitster Canada (Franco)</div>
|
||||
<div class="playlist-item">Hitster Guilty Pleasures (CA)</div>
|
||||
<div class="playlist-item">Hitster Guilty Pleasures (NOR)</div>
|
||||
<div class="playlist-item">Hitster Italia</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<span>Linkster — linkster.langhei.de</span>
|
||||
<span>
|
||||
<a href="#impressum">Impressum</a>
|
||||
 · 
|
||||
<a href="#datenschutz">Datenschutz</a>
|
||||
</span>
|
||||
</footer>
|
||||
|
||||
<div class="legal">
|
||||
|
||||
<h2 id="impressum">Impressum</h2>
|
||||
|
||||
<h3>Angaben gemäß § 5 TMG</h3>
|
||||
<address>
|
||||
Mario Störmer<br>
|
||||
Langheide 14<br>
|
||||
24354 Rieseby<br>
|
||||
Deutschland
|
||||
</address>
|
||||
|
||||
<h3>Hinweis</h3>
|
||||
<p>
|
||||
Dieses Angebot ist ein privates, nicht-kommerzielles Hobbyprojekt.
|
||||
Es werden keine wirtschaftlichen Interessen verfolgt und kein Entgelt erhoben.
|
||||
</p>
|
||||
|
||||
<h2 id="datenschutz">Datenschutzerklärung</h2>
|
||||
|
||||
<h3>Verantwortlicher</h3>
|
||||
<address>
|
||||
Mario Störmer<br>
|
||||
Langheide 14<br>
|
||||
24354 Rieseby<br>
|
||||
Deutschland
|
||||
</address>
|
||||
|
||||
<h3>Welche Daten werden verarbeitet?</h3>
|
||||
<p>
|
||||
Beim Aufruf dieser Seite und der API werden technisch bedingt folgende Daten
|
||||
kurzfristig im Server-Log gespeichert:
|
||||
</p>
|
||||
<p>
|
||||
IP-Adresse des anfragenden Geräts, aufgerufene URL, Zeitpunkt der Anfrage sowie
|
||||
HTTP-Statuscode. Diese Daten sind für den stabilen Betrieb des Dienstes notwendig
|
||||
und werden nicht an Dritte weitergegeben.
|
||||
</p>
|
||||
|
||||
<h3>Zweck der Verarbeitung</h3>
|
||||
<p>
|
||||
Die Daten werden ausschließlich zur Fehleranalyse und Sicherstellung des Betriebs
|
||||
verwendet. Eine Auswertung zu Analyse-, Tracking- oder Werbezwecken findet nicht statt.
|
||||
</p>
|
||||
|
||||
<h3>Speicherdauer</h3>
|
||||
<p>
|
||||
Server-Logs werden automatisch nach 30 Tagen gelöscht. Es erfolgt keine
|
||||
dauerhafte Speicherung personenbezogener Daten.
|
||||
</p>
|
||||
|
||||
<h3>Cookies & Tracking</h3>
|
||||
<p>
|
||||
Diese Website verwendet keine Cookies, keine Analyse-Tools und kein Tracking
|
||||
jeglicher Art.
|
||||
</p>
|
||||
|
||||
<h3>Weitergabe an Dritte</h3>
|
||||
<p>
|
||||
Es findet keine Weitergabe von Daten an Dritte statt. Der Dienst ist
|
||||
ausschließlich für den privaten Gebrauch bestimmt.
|
||||
</p>
|
||||
|
||||
<h3>Rechte betroffener Personen</h3>
|
||||
<p>
|
||||
Gemäß DSGVO stehen Ihnen das Recht auf Auskunft, Berichtigung, Löschung und
|
||||
Einschränkung der Verarbeitung zu. Anfragen können per Post an die oben genannte
|
||||
Adresse gerichtet werden.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
build/resources/main/static/linkster.apk
Normal file
BIN
build/resources/main/static/linkster.apk
Normal file
Binary file not shown.
12
build/tmp/bootJar/MANIFEST.MF
Normal file
12
build/tmp/bootJar/MANIFEST.MF
Normal file
@@ -0,0 +1,12 @@
|
||||
Manifest-Version: 1.0
|
||||
Main-Class: org.springframework.boot.loader.launch.JarLauncher
|
||||
Start-Class: de.oaa.linkster.LinksterApplication
|
||||
Spring-Boot-Version: 3.2.3
|
||||
Spring-Boot-Classes: BOOT-INF/classes/
|
||||
Spring-Boot-Lib: BOOT-INF/lib/
|
||||
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
|
||||
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
|
||||
Build-Jdk-Spec: 17
|
||||
Implementation-Title: linkster-backend
|
||||
Implementation-Version: 0.0.1-SNAPSHOT
|
||||
|
||||
BIN
build/tmp/compileJava/previous-compilation-data.bin
Normal file
BIN
build/tmp/compileJava/previous-compilation-data.bin
Normal file
Binary file not shown.
19
deploy.sh
Executable file
19
deploy.sh
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
REMOTE_CONTEXT="proxmox-remote"
|
||||
IMAGE_NAME="linkster-backend"
|
||||
TAG="latest"
|
||||
|
||||
echo "--- 1. Gradle Build: Erstelle JAR und Docker Image lokal ---"
|
||||
./gradlew bootJar
|
||||
docker build -t $IMAGE_NAME:$TAG .
|
||||
|
||||
echo "--- 2. Transfer: Image zum Proxmox-Server schieben ---"
|
||||
docker save $IMAGE_NAME:$TAG | docker --context $REMOTE_CONTEXT load
|
||||
|
||||
echo "--- 3. Remote Deployment: Starten auf Proxmox ---"
|
||||
docker --context $REMOTE_CONTEXT compose up -d --force-recreate
|
||||
|
||||
echo "--- Fertig! Backend läuft auf Port 8090 ---"
|
||||
echo "--- Erreichbar unter: https://linkster.langhei.de/api/ ---"
|
||||
14
docker-compose.yml
Normal file
14
docker-compose.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
services:
|
||||
linkster-backend:
|
||||
image: linkster-backend:latest
|
||||
container_name: linkster-backend
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8090:8090"
|
||||
environment:
|
||||
- SPRING_PROFILES_ACTIVE=prod
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8090/api/health"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
221
gradlew
vendored
Executable file
221
gradlew
vendored
Executable file
@@ -0,0 +1,221 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by "Gradle init".
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other POSIX-compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for contributing:
|
||||
#
|
||||
# (2) This script should remain compatible with sh and target the lowest common
|
||||
# denominator POSIX shell, even when local shells might be more capable.
|
||||
# POSIX features are given preference over "smarts" that would make the
|
||||
# script easier to write or maintain, or that might otherwise work on
|
||||
# non-POSIX-compliant shells.
|
||||
#
|
||||
# (3) This script must be sourced from the root directory of the project, not
|
||||
# from outside it.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #( absolute
|
||||
*) app_path=$APP_HOME$link ;; #( relative
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
;;
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #( No-op if MAX_FD is empty or 'soft'
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# temporary variables. (ref: https://unix.stackexchange.com/a/338087)
|
||||
set -- "$@" "$arg"
|
||||
shift
|
||||
done
|
||||
fi
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
# shellcheck disable=SC2086
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# temporary variable that contains a space. They are then exported to the
|
||||
# function, which does the final interpretation.
|
||||
#
|
||||
# NOTE: The sed script strips any leading and trailing whitespace as we
|
||||
# don't want to add extra whitespace to the args.
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^a-zA-Z0-9/=@._-]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
) $@"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
1
settings.gradle
Normal file
1
settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'linkster-backend'
|
||||
11
src/main/java/de/oaa/linkster/LinksterApplication.java
Normal file
11
src/main/java/de/oaa/linkster/LinksterApplication.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package de.oaa.linkster;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class LinksterApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(LinksterApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package de.oaa.linkster.controller;
|
||||
|
||||
import de.oaa.linkster.model.ResolveResponse;
|
||||
import de.oaa.linkster.service.PlaylistService;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
public class ResolveController {
|
||||
|
||||
private final PlaylistService playlistService;
|
||||
|
||||
public ResolveController(PlaylistService playlistService) {
|
||||
this.playlistService = playlistService;
|
||||
}
|
||||
|
||||
@GetMapping("/resolve")
|
||||
public ResponseEntity<ResolveResponse> resolve(@RequestParam String url) {
|
||||
ResolveResponse response = playlistService.resolve(url);
|
||||
if (response.isFound()) {
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
return ResponseEntity.ok(response); // 200 mit found=false, App entscheidet
|
||||
}
|
||||
|
||||
@GetMapping("/health")
|
||||
public ResponseEntity<String> health() {
|
||||
return ResponseEntity.ok("ok");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package de.oaa.linkster.filter;
|
||||
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Component
|
||||
public class RequestLoggingFilter implements Filter {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RequestLoggingFilter.class);
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
|
||||
HttpServletRequest request = (HttpServletRequest) req;
|
||||
HttpServletResponse response = (HttpServletResponse) res;
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
try {
|
||||
chain.doFilter(req, res);
|
||||
} finally {
|
||||
long ms = System.currentTimeMillis() - start;
|
||||
String query = request.getQueryString();
|
||||
String uri = query != null ? request.getRequestURI() + "?" + query : request.getRequestURI();
|
||||
int status = response.getStatus();
|
||||
|
||||
if (status >= 500) {
|
||||
log.error("{} {} {} {}ms", request.getMethod(), uri, status, ms);
|
||||
} else if (status >= 400) {
|
||||
log.warn("{} {} {} {}ms", request.getMethod(), uri, status, ms);
|
||||
} else {
|
||||
log.info("{} {} {} {}ms", request.getMethod(), uri, status, ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
src/main/java/de/oaa/linkster/model/ResolveResponse.java
Normal file
36
src/main/java/de/oaa/linkster/model/ResolveResponse.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package de.oaa.linkster.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ResolveResponse {
|
||||
|
||||
private final boolean found;
|
||||
private String title;
|
||||
private String artist;
|
||||
private String playlist;
|
||||
private Map<String, String> providers;
|
||||
|
||||
private ResolveResponse(boolean found) {
|
||||
this.found = found;
|
||||
}
|
||||
|
||||
public static ResolveResponse notFound() {
|
||||
return new ResolveResponse(false);
|
||||
}
|
||||
|
||||
public static ResolveResponse of(String title, String artist, String playlist,
|
||||
Map<String, String> providers) {
|
||||
ResolveResponse r = new ResolveResponse(true);
|
||||
r.title = title;
|
||||
r.artist = artist;
|
||||
r.playlist = playlist;
|
||||
r.providers = providers;
|
||||
return r;
|
||||
}
|
||||
|
||||
public boolean isFound() { return found; }
|
||||
public String getTitle() { return title; }
|
||||
public String getArtist() { return artist; }
|
||||
public String getPlaylist() { return playlist; }
|
||||
public Map<String, String> getProviders() { return providers; }
|
||||
}
|
||||
119
src/main/java/de/oaa/linkster/service/PlaylistService.java
Normal file
119
src/main/java/de/oaa/linkster/service/PlaylistService.java
Normal file
@@ -0,0 +1,119 @@
|
||||
package de.oaa.linkster.service;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import de.oaa.linkster.model.ResolveResponse;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Service
|
||||
public class PlaylistService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(PlaylistService.class);
|
||||
|
||||
private record PlaylistEntry(String id, String name, Pattern matcher) {}
|
||||
|
||||
/** In-Memory-DB: playlistId → songId → SongData */
|
||||
private final ConcurrentHashMap<String, ConcurrentHashMap<String, JsonObject>> db
|
||||
= new ConcurrentHashMap<>();
|
||||
|
||||
private final List<PlaylistEntry> index = new ArrayList<>();
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
try {
|
||||
JsonArray all = readJson("playlists/all.json").getAsJsonArray();
|
||||
for (JsonElement elem : all) {
|
||||
JsonObject obj = elem.getAsJsonObject();
|
||||
if (!obj.has("matcher")) continue;
|
||||
if (obj.has("available") && !obj.get("available").getAsBoolean()) continue;
|
||||
|
||||
String id = obj.get("id").getAsString();
|
||||
String name = obj.get("name").getAsString();
|
||||
String raw = obj.get("matcher").getAsString();
|
||||
String pattern = raw.replaceAll("^/|/[a-z]*$", "");
|
||||
|
||||
try {
|
||||
index.add(new PlaylistEntry(id, name, Pattern.compile(pattern)));
|
||||
loadPlaylist(id);
|
||||
} catch (Exception e) {
|
||||
log.warn("Überspringe Playlist {}: {}", id, e.getMessage());
|
||||
}
|
||||
}
|
||||
log.info("Linkster-DB bereit: {} Playlists geladen", db.size());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Fehler beim Laden der Playlists", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadPlaylist(String id) throws Exception {
|
||||
JsonObject playlist = readJson("playlists/" + id + ".json").getAsJsonObject();
|
||||
JsonObject songs = playlist.getAsJsonObject("songs");
|
||||
ConcurrentHashMap<String, JsonObject> songMap = new ConcurrentHashMap<>();
|
||||
for (Map.Entry<String, JsonElement> entry : songs.entrySet()) {
|
||||
songMap.put(entry.getKey(), entry.getValue().getAsJsonObject());
|
||||
}
|
||||
db.put(id, songMap);
|
||||
log.debug(" {} → {} Songs", id, songMap.size());
|
||||
}
|
||||
|
||||
public ResolveResponse resolve(String url) {
|
||||
for (PlaylistEntry entry : index) {
|
||||
Matcher m = entry.matcher().matcher(url);
|
||||
if (!m.find()) continue;
|
||||
|
||||
int songId = Integer.parseInt(m.group(1));
|
||||
ConcurrentHashMap<String, JsonObject> songs = db.get(entry.id());
|
||||
if (songs == null) continue;
|
||||
|
||||
JsonObject song = songs.get(String.valueOf(songId));
|
||||
if (song == null) continue;
|
||||
|
||||
String title = song.get("title").getAsString();
|
||||
String artist = song.get("artistName").getAsString();
|
||||
Map<String, String> providers = extractProviders(song);
|
||||
|
||||
return ResolveResponse.of(title, artist, entry.name(), providers);
|
||||
}
|
||||
return ResolveResponse.notFound();
|
||||
}
|
||||
|
||||
private Map<String, String> extractProviders(JsonObject song) {
|
||||
Map<String, String> result = new LinkedHashMap<>();
|
||||
JsonObject providers = song.getAsJsonObject("providers");
|
||||
if (providers == null) return result;
|
||||
for (Map.Entry<String, JsonElement> p : providers.entrySet()) {
|
||||
JsonObject regions = p.getValue().getAsJsonObject();
|
||||
for (Map.Entry<String, JsonElement> r : regions.entrySet()) {
|
||||
String url = r.getValue().getAsString();
|
||||
if (url != null && !url.isEmpty()) {
|
||||
result.put(p.getKey(), url);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private JsonElement readJson(String path) throws Exception {
|
||||
try (var is = new ClassPathResource(path).getInputStream();
|
||||
var reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
|
||||
return JsonParser.parseReader(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
src/main/resources/application.properties
Normal file
2
src/main/resources/application.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
server.port=8090
|
||||
spring.application.name=linkster-backend
|
||||
35
src/main/resources/logback-spring.xml
Normal file
35
src/main/resources/logback-spring.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<configuration>
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE_ERRORS" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>logs/errors.log</file>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>WARN</level>
|
||||
</filter>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>logs/errors.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="de.oaa.linkster" level="INFO"/>
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE_ERRORS"/>
|
||||
</root>
|
||||
|
||||
<logger name="de.oaa.linkster" level="INFO" additivity="false">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE_ERRORS"/>
|
||||
</logger>
|
||||
|
||||
</configuration>
|
||||
256
src/main/resources/playlists/all.json
Normal file
256
src/main/resources/playlists/all.json
Normal file
@@ -0,0 +1,256 @@
|
||||
[
|
||||
{
|
||||
"id": "hitster-bingo-deutschland",
|
||||
"name": "Hitster Bingo Deutschland",
|
||||
"matcher": "/de/aaaa0019/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-ca",
|
||||
"name": "Hitster Canada",
|
||||
"matcher": "/ca/aaad0001/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-ca-franco",
|
||||
"name": "Hitster Canada (Franco)",
|
||||
"matcher": "/ca/aaad0002/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-ca-guilty-pleasures",
|
||||
"name": "Hitster Guilty Pleasures (CA)",
|
||||
"matcher": "/ca/aaad0003/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de",
|
||||
"name": "Hitster Deutsch",
|
||||
"matcher": "/de/(\\d{5})$/",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
},
|
||||
"available": true
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-bayern-1-expansion",
|
||||
"name": "Hitster Bayern 1 Expansion (DE)",
|
||||
"matcher": "/de/aaaa0025/(\\d{5})$/",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "no",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
},
|
||||
"available": true
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-celebration",
|
||||
"name": "Hitster Celebration (DE)",
|
||||
"matcher": "/de/aaaa0040/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-guilty-pleasures",
|
||||
"name": "Hitster Guilty Pleasures (DE)",
|
||||
"matcher": "/de/aaaa0015/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-rock",
|
||||
"name": "Hitster Rock (DE)",
|
||||
"matcher": "/de/aaaa0039/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-schlager-party",
|
||||
"name": "Hitster Schlager Party (DE)",
|
||||
"matcher": "/de/aaaa0007/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-soundtracks-expansion",
|
||||
"name": "Hitster Soundtracks Expansion (DE)",
|
||||
"matcher": "/de/aaaa0026/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-de-summer-party",
|
||||
"name": "Hitster Summer Party (DE)",
|
||||
"matcher": "/de/aaaa0012/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-guilty-pleasures-nor",
|
||||
"name": "Hitster Guilty Pleasures (NOR)",
|
||||
"matcher": "/dk/aaaa0024/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "full",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-it",
|
||||
"name": "Hitster Italia",
|
||||
"matcher": "/it/aaac0001/(\\d{5})$/",
|
||||
"available": true,
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "full",
|
||||
"youtubeMusic": "full"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "hitster-uk",
|
||||
"name": "Hitster UK",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "no",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "no",
|
||||
"youtubeMusic": "no"
|
||||
},
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"id": "hitster-usa",
|
||||
"name": "Hitster USA",
|
||||
"support": {
|
||||
"appleMusic": "full",
|
||||
"amazonMusic": "full",
|
||||
"deezer": "full",
|
||||
"soundcloud": "no",
|
||||
"spotify": "full",
|
||||
"tidal": "full",
|
||||
"youtube": "no",
|
||||
"youtubeMusic": "no"
|
||||
},
|
||||
"available": false
|
||||
}
|
||||
]
|
||||
6993
src/main/resources/playlists/hitster-bingo-deutschland.json
Normal file
6993
src/main/resources/playlists/hitster-bingo-deutschland.json
Normal file
File diff suppressed because it is too large
Load Diff
9450
src/main/resources/playlists/hitster-ca-franco.json
Normal file
9450
src/main/resources/playlists/hitster-ca-franco.json
Normal file
File diff suppressed because it is too large
Load Diff
9566
src/main/resources/playlists/hitster-ca-guilty-pleasures.json
Normal file
9566
src/main/resources/playlists/hitster-ca-guilty-pleasures.json
Normal file
File diff suppressed because it is too large
Load Diff
9548
src/main/resources/playlists/hitster-ca.json
Normal file
9548
src/main/resources/playlists/hitster-ca.json
Normal file
File diff suppressed because it is too large
Load Diff
4776
src/main/resources/playlists/hitster-de-bayern-1-expansion.json
Normal file
4776
src/main/resources/playlists/hitster-de-bayern-1-expansion.json
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user