Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba0ab6d57b | ||
|
|
ef17ad203d | ||
|
|
19f08d36cf | ||
|
|
141c8f1659 | ||
|
|
dd677afff0 | ||
|
|
cc0d502229 | ||
|
|
0d32740ec7 | ||
|
|
839236ecd1 | ||
|
|
4c7a9e27e3 | ||
|
|
08879a6860 | ||
|
|
f72645e05c | ||
|
|
e834e0f096 | ||
|
|
4eca38ad24 | ||
|
|
7543f07562 | ||
|
|
a90be58013 | ||
|
|
93a643d10d | ||
|
|
85c52fac2a | ||
|
|
8239e387fb | ||
|
|
b4e17d6853 | ||
|
|
ca16e3c43a | ||
|
|
5f9247391a | ||
|
|
ee12030cf6 | ||
|
|
b062fb0b97 | ||
|
|
01c72af17a | ||
|
|
b28eb6d3b7 | ||
|
|
5d2392ad9e | ||
|
|
efb334f8de | ||
|
|
d4b1c6a9e1 | ||
|
|
f7a62560c7 | ||
|
|
e7393c0192 | ||
|
|
bc647ce9be | ||
|
|
af6cb7d1ec | ||
|
|
a88e7d2ce5 | ||
| 3d78b90ff1 | |||
| 3d7ee42ca8 | |||
| 77acd2060b | |||
| 88f65f0806 | |||
| 6df71e3341 | |||
| 263a4ae4c0 | |||
| 57a48de52f | |||
| ae9f00a60a | |||
| 93b95becb7 | |||
| bd66703a08 | |||
| 86fec254aa | |||
| 6f16bffe31 | |||
| 1fc1b5d35d | |||
| 7d6e3bb8c8 | |||
| 11b8b575e4 | |||
| dfa245e842 | |||
| ed94562372 | |||
| 5fee3a1390 | |||
| 96bc7ec052 | |||
| 94d2fd0fc8 | |||
| d8ceaef3f9 | |||
| 334d68ac1f | |||
| e4831e1a17 | |||
| e0b81d2122 | |||
| 95c3c0f968 | |||
| 154c825499 | |||
| 5e8b244ebd | |||
| 48ad545da1 | |||
| 4b002aaee4 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -53,6 +53,8 @@ testem.log
|
|||||||
# System Files
|
# System Files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
/env_dev/data
|
||||||
|
/env_dev/dataMongo
|
||||||
|
|
||||||
backPY/env
|
backPY/env
|
||||||
|
|
||||||
@@ -62,3 +64,5 @@ __pycache__
|
|||||||
|
|
||||||
.design/
|
.design/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
front/storybook-static
|
||||||
|
back/bin
|
||||||
|
|||||||
@@ -1,7 +1,32 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
version_file="../version.txt"
|
||||||
|
|
||||||
|
# update new release dependency
|
||||||
cd back
|
cd back
|
||||||
mvn versions:set -DnewVersion=$(cat ../version.txt)
|
# update the Maven version number
|
||||||
|
mvn versions:set -DnewVersion=$(sed 's/dev/SNAPSHOT/g' $version_file)
|
||||||
|
if grep -q "DEV" "$version_file"; then
|
||||||
|
# update all versions release of dependency
|
||||||
|
mvn versions:use-latest-releases
|
||||||
|
# update our manage dependency as snapshoot
|
||||||
|
mvn versions:use-latest-versions -Dincludes=kangaroo-and-rabbit
|
||||||
|
else
|
||||||
|
# update our manage dependency as release (must be done before)
|
||||||
|
mvn versions:use-latest-releases -Dincludes=kangaroo-and-rabbit
|
||||||
|
fi
|
||||||
cd -
|
cd -
|
||||||
|
|
||||||
|
|
||||||
|
cd front
|
||||||
|
if grep -q "dev" "$version_file"; then
|
||||||
|
# update all dependency
|
||||||
|
pnpm install
|
||||||
|
pnpm run update_packages
|
||||||
|
else
|
||||||
|
# in case of release ==> can not do it automatically ...
|
||||||
|
echo not implemented
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd -
|
||||||
|
|
||||||
|
|||||||
102
Dockerfile
102
Dockerfile
@@ -1,25 +1,33 @@
|
|||||||
######################################################################################
|
######################################################################################
|
||||||
##
|
##
|
||||||
## buyilding-end install applications:
|
## building-end install applications:
|
||||||
##
|
##
|
||||||
######################################################################################
|
######################################################################################
|
||||||
FROM archlinux:base-devel AS builder
|
FROM archlinux:base-devel AS common
|
||||||
# update system
|
# update system
|
||||||
RUN pacman -Syu --noconfirm && pacman-db-upgrade \
|
RUN pacman -Syu --noconfirm && pacman-db-upgrade \
|
||||||
&& pacman -S --noconfirm jdk-openjdk maven npm \
|
&& pacman -S --noconfirm jdk-openjdk wget\
|
||||||
&& pacman -Scc --noconfirm
|
&& pacman -Scc --noconfirm
|
||||||
|
|
||||||
ENV PATH /tmp/node_modules/.bin:$PATH
|
|
||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
|
|
||||||
|
FROM common AS builder
|
||||||
|
# update system
|
||||||
|
RUN pacman -Syu --noconfirm && pacman-db-upgrade \
|
||||||
|
&& pacman -S --noconfirm maven npm pnpm \
|
||||||
|
&& pacman -Scc --noconfirm
|
||||||
|
|
||||||
|
ENV PATH=/tmp/node_modules/.bin:$PATH
|
||||||
|
|
||||||
######################################################################################
|
######################################################################################
|
||||||
##
|
##
|
||||||
## Build back:
|
## Build back:
|
||||||
##
|
##
|
||||||
######################################################################################
|
######################################################################################
|
||||||
FROM builder AS buildBack
|
FROM builder AS build_back
|
||||||
COPY back/pom.xml /tmp
|
COPY back/pom.xml ./
|
||||||
COPY back/src /tmp/src/
|
COPY back/Formatter.xml ./
|
||||||
|
COPY back/src ./src/
|
||||||
RUN mvn clean compile assembly:single
|
RUN mvn clean compile assembly:single
|
||||||
|
|
||||||
######################################################################################
|
######################################################################################
|
||||||
@@ -27,26 +35,44 @@ RUN mvn clean compile assembly:single
|
|||||||
## Build front:
|
## Build front:
|
||||||
##
|
##
|
||||||
######################################################################################
|
######################################################################################
|
||||||
FROM builder AS buildFront
|
FROM builder AS dependency_front
|
||||||
|
|
||||||
ADD front/package-lock.json \
|
RUN echo "@kangaroo-and-rabbit:registry=https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/npm/" > /root/.npmrc
|
||||||
front/package.json \
|
|
||||||
front/karma.conf.js \
|
COPY front/package.json \
|
||||||
front/protractor.conf.js \
|
front/pnpm-lock.yaml \
|
||||||
/tmp/
|
./
|
||||||
|
COPY front/src/theme ./src/theme
|
||||||
|
|
||||||
# install and cache app dependencies
|
# install and cache app dependencies
|
||||||
RUN npm install
|
RUN pnpm install --prod=false
|
||||||
|
|
||||||
ADD front/e2e \
|
###############################################################
|
||||||
|
## Install sources
|
||||||
|
###############################################################
|
||||||
|
FROM dependency_front AS load_sources_front
|
||||||
|
|
||||||
|
# JUST to get the version of the application and his sha...
|
||||||
|
COPY \
|
||||||
front/tsconfig.json \
|
front/tsconfig.json \
|
||||||
front/tslint.json \
|
front/tsconfig.node.json \
|
||||||
front/angular.json \
|
front/vite.config.mts \
|
||||||
/tmp/
|
front/index.html \
|
||||||
ADD front/src /tmp/src
|
./
|
||||||
|
|
||||||
# generate build
|
COPY front/public ./public
|
||||||
RUN ng build --output-path=dist --configuration=production --base-href=/karideo/ --deploy-url=/karideo/
|
COPY front/src ./src
|
||||||
|
|
||||||
|
# We are not in prod mode ==> we need to overwrite the production env.
|
||||||
|
ARG env=front/.env.production
|
||||||
|
COPY ${env} .env
|
||||||
|
|
||||||
|
###############################################################
|
||||||
|
## Build the sources
|
||||||
|
###############################################################
|
||||||
|
FROM load_sources_front AS build_front
|
||||||
|
# build in bundle mode all the application
|
||||||
|
RUN pnpm static:build
|
||||||
|
|
||||||
######################################################################################
|
######################################################################################
|
||||||
##
|
##
|
||||||
@@ -54,26 +80,24 @@ RUN ng build --output-path=dist --configuration=production --base-href=/karideo/
|
|||||||
##
|
##
|
||||||
######################################################################################
|
######################################################################################
|
||||||
|
|
||||||
FROM bellsoft/liberica-openjdk-alpine:latest
|
FROM bellsoft/liberica-openjdk-alpine-musl:latest
|
||||||
# add wget to manage the health check...
|
|
||||||
RUN apk add --no-cache wget
|
|
||||||
|
|
||||||
#FROM archlinux:base
|
RUN apk add --no-cache wget \
|
||||||
#RUN pacman -Syu --noconfirm && pacman-db-upgrade
|
&& addgroup -g 1000 user \
|
||||||
## install package
|
&& adduser --system -u 1000 -G user user
|
||||||
#RUN pacman -S --noconfirm jdk-openjdk wget
|
|
||||||
## intall npm
|
|
||||||
#RUN pacman -S --noconfirm npm
|
|
||||||
## clean all the caches Need only on the release environment
|
|
||||||
#RUN pacman -Scc --noconfirm
|
|
||||||
|
|
||||||
ENV LANG=C.UTF-8
|
ENV LANG=C.UTF-8
|
||||||
|
|
||||||
COPY --from=buildBack /tmp/out/maven/*.jar /application/application.jar
|
|
||||||
COPY --from=buildFront /tmp/dist /application/front/
|
|
||||||
|
|
||||||
WORKDIR /application/
|
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
WORKDIR /application/
|
||||||
|
RUN chown user:user -R /application
|
||||||
|
|
||||||
CMD ["java", "-Xms64M", "-Xmx1G", "-cp", "/application/application.jar", "org.kar.karideo.WebLauncher"]
|
# To verify health-check: docker inspect --format "{{json .State.Health }}" YOUR_SERVICE_NAME | jq
|
||||||
|
HEALTHCHECK --start-period=10s --start-interval=2s --interval=30s --timeout=5s --retries=10 \
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://localhost:80/api/health_check || exit 1
|
||||||
|
|
||||||
|
CMD ["java", "-Xms128M", "-Xmx1G", "-cp", "/application/application.jar", "org.atriasoft.karideo.WebLauncher"]
|
||||||
|
|
||||||
|
COPY --chown=user:user --from=build_back /tmp/out/maven/*.jar /application/application.jar
|
||||||
|
COPY --chown=user:user --from=build_front /tmp/dist /application/front/
|
||||||
|
|
||||||
|
USER user
|
||||||
|
|||||||
145
README.md
Normal file
145
README.md
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
Karideo
|
||||||
|
=======
|
||||||
|
|
||||||
|
**K**angaroo **A**nd **R**abbit (v)ideo is a simple framework to propose video streaming for personal network
|
||||||
|
|
||||||
|
Run in local:
|
||||||
|
=============
|
||||||
|
|
||||||
|
Start tools
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Start the server basic interfaces: (DB(mySQL), Adminer)
|
||||||
|
|
||||||
|
```{.bash}
|
||||||
|
# start the Bdd interface (no big data > 50Mo)
|
||||||
|
docker compose -f env_dev/docker-compose.yaml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Start the Back-end:
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
backend is developed in JAVA
|
||||||
|
|
||||||
|
The first step is configuring your JAVA version (or select the JVM with the OS)
|
||||||
|
```bash
|
||||||
|
export PATH=$(ls -d --color=never /usr/lib/jvm/java-2*-openjdk)/bin:$PATH
|
||||||
|
```
|
||||||
|
|
||||||
|
Install the dependency:
|
||||||
|
```bash
|
||||||
|
mvn install
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the test
|
||||||
|
```bash
|
||||||
|
mvn test
|
||||||
|
```
|
||||||
|
|
||||||
|
Install it for external use
|
||||||
|
```bash
|
||||||
|
mvn install
|
||||||
|
```
|
||||||
|
|
||||||
|
Execute the local server:
|
||||||
|
```bash
|
||||||
|
mvn exec:java@dev-mode
|
||||||
|
```
|
||||||
|
|
||||||
|
Start the Front-end:
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
backend is developed in JAVA
|
||||||
|
```bash
|
||||||
|
cd front
|
||||||
|
pnpm install
|
||||||
|
pnpm dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Display the result:
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
[show the webpage: http://localhost:4203](http://localhost:4203)
|
||||||
|
|
||||||
|
Some other dev tools:
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Format code:
|
||||||
|
------------
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export PATH=$(ls -d --color=never /usr/lib/jvm/java-2*-openjdk)/bin:$PATH
|
||||||
|
mvn formatter:format
|
||||||
|
mvn test
|
||||||
|
```
|
||||||
|
|
||||||
|
Tools in production mode
|
||||||
|
========================
|
||||||
|
|
||||||
|
Changing the Log Level
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
In a production environment, you can adjust the log level to help diagnose bugs more effectively.
|
||||||
|
|
||||||
|
The available log levels are:
|
||||||
|
| **Log Level Tag** | **org.kar.karideo** | **org.kar.archidata** | **other** |
|
||||||
|
| ----------------- | ------------------- | --------------------- | --------- |
|
||||||
|
| `prod` | INFO | INFO | INFO |
|
||||||
|
| `prod-debug` | DEBUG | INFO | INFO |
|
||||||
|
| `prod-trace` | TRACE | DEBUG | INFO |
|
||||||
|
| `prod-trace-full` | TRACE | TRACE | INFO |
|
||||||
|
| `dev` | TRACE | DEBUG | INFO |
|
||||||
|
|
||||||
|
|
||||||
|
Manual set in production:
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Connect on the registry
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
To log-in and log-out from the registry:
|
||||||
|
```bash
|
||||||
|
export REGISTRY_ADDRESS=gitea.atria-soft.org
|
||||||
|
docker login -u <<YOUR_USER_NAME>> ${REGISTRY_ADDRESS}
|
||||||
|
docker logout ${REGISTRY_ADDRESS}
|
||||||
|
```
|
||||||
|
|
||||||
|
pull the root image of dockers
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker pull archlinux:base-devel
|
||||||
|
docker pull bellsoft/liberica-openjdk-alpine:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy on mongodb
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
connect on the mongosh interface:
|
||||||
|
```bash
|
||||||
|
docker compose exec kar_mongodb_service mongosh -u root
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the base and the user
|
||||||
|
```
|
||||||
|
use karideo
|
||||||
|
db.createUser({
|
||||||
|
user: "karideo",
|
||||||
|
pwd: "your_password",
|
||||||
|
roles: [
|
||||||
|
{ role: "readWrite", db: "karideo" }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the version
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Execute in the local folder: (use ```dev``` for development and ```latest``` for production release)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export TAG_DOCKER=latest
|
||||||
|
export REGISTRY_ADDRESS=gitea.atria-soft.org
|
||||||
|
docker build -t ${REGISTRY_ADDRESS}/kangaroo-and-rabbit/karideo:${TAG_DOCKER} .
|
||||||
|
docker push ${REGISTRY_ADDRESS}/kangaroo-and-rabbit/karideo:${TAG_DOCKER}
|
||||||
|
```
|
||||||
@@ -53,6 +53,9 @@ Checkstyle configuration that checks the sun coding conventions.
|
|||||||
<module name="LambdaParameterName"/>
|
<module name="LambdaParameterName"/>
|
||||||
<module name="Regexp"/>
|
<module name="Regexp"/>
|
||||||
<module name="RegexpSinglelineJava"/>
|
<module name="RegexpSinglelineJava"/>
|
||||||
|
<module name="UnusedPrivateField">
|
||||||
|
<property name="ignorePattern" value="LOGGER"/>
|
||||||
|
</module>
|
||||||
</module>
|
</module>
|
||||||
<module name="BeforeExecutionExclusionFileFilter">
|
<module name="BeforeExecutionExclusionFileFilter">
|
||||||
<property name="fileNamePattern" value="module\-info\.java$"/>
|
<property name="fileNamePattern" value="module\-info\.java$"/>
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
FROM maven:3.6.3-openjdk-16 AS build
|
|
||||||
|
|
||||||
COPY pom.xml /tmp/
|
|
||||||
COPY src /tmp/src/
|
|
||||||
WORKDIR /tmp/
|
|
||||||
RUN mvn clean compile assembly:single
|
|
||||||
|
|
||||||
FROM bellsoft/liberica-openjdk-alpine:latest
|
|
||||||
ENV LANG=C.UTF-8
|
|
||||||
|
|
||||||
# add wget to manage the health check...
|
|
||||||
RUN apk add --no-cache wget
|
|
||||||
|
|
||||||
RUN mkdir /application/
|
|
||||||
COPY --from=build /tmp/out/maven/*.jar /application/application.jar
|
|
||||||
WORKDIR /application/
|
|
||||||
|
|
||||||
EXPOSE 18080
|
|
||||||
|
|
||||||
CMD ["java", "-Xms64M", "-Xmx1G", "-cp", "/application/application.jar", "org.kar.karideo.WebLauncher"]
|
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ mvn package
|
|||||||
// download all dependency in out/maven/dependency
|
// download all dependency in out/maven/dependency
|
||||||
mvn dependency:copy-dependencies
|
mvn dependency:copy-dependencies
|
||||||
|
|
||||||
java -cp out/maven/kar-karideo-0.1.0.jar org.kar.karideo.WebLauncher
|
java -cp out/maven/kar-karideo-0.1.0.jar org.atriasoft.karideo.WebLauncher
|
||||||
|
|
||||||
|
|
||||||
// create a single package jar
|
// create a single package jar
|
||||||
@@ -19,7 +19,7 @@ mvn clean compile assembly:single
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
java -cp out/maven/karideo-0.1.0-jar-with-dependencies.jar org.kar.karideo.WebLauncher
|
java -cp out/maven/karideo-0.1.0-jar-with-dependencies.jar org.atriasoft.karideo.WebLauncher
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
188
back/pom.xml
188
back/pom.xml
@@ -1,31 +1,47 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.kar</groupId>
|
<groupId>org.atriasoft</groupId>
|
||||||
<artifactId>karideo</artifactId>
|
<artifactId>karideo</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.version>3.1</maven.compiler.version>
|
<maven.compiler.version>3.13.0</maven.compiler.version>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>23</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>23</maven.compiler.target>
|
||||||
<maven.dependency.version>3.1.1</maven.dependency.version>
|
<maven.dependency.version>3.1.1</maven.dependency.version>
|
||||||
</properties>
|
</properties>
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>gitea</id>
|
|
||||||
<url>https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>kangaroo-and-rabbit</groupId>
|
<groupId>org.atria-soft</groupId>
|
||||||
<artifactId>archidata</artifactId>
|
<artifactId>archidata</artifactId>
|
||||||
<version>0.6.1</version>
|
<version>0.37.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- Loopback of logger JDK logging API to SLF4J -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-simple</artifactId>
|
<artifactId>jul-to-slf4j</artifactId>
|
||||||
<version>2.0.9</version>
|
<version>2.1.0-alpha1</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- generic logger of SLF4J to console (in color) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>1.5.19</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>xerces</groupId>
|
||||||
|
<artifactId>xercesImpl</artifactId>
|
||||||
|
<version>2.12.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.janino</groupId>
|
||||||
|
<artifactId>janino</artifactId>
|
||||||
|
<version>3.1.12</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
<version>2.20.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--
|
<!--
|
||||||
************************************************************
|
************************************************************
|
||||||
@@ -35,15 +51,25 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
<version>5.10.1</version>
|
<version>6.0.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>5.10.1</version>
|
<version>6.0.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.revelc.code.formatter</groupId>
|
||||||
|
<artifactId>formatter-maven-plugin</artifactId>
|
||||||
|
<version>2.29.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<sourceDirectory>src</sourceDirectory>
|
<sourceDirectory>src</sourceDirectory>
|
||||||
@@ -72,16 +98,45 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>exec-maven-plugin</artifactId>
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
<version>1.4.0</version>
|
<version>3.2.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>prod-mode</id>
|
||||||
|
<goals>
|
||||||
|
<goal>java</goal>
|
||||||
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<mainClass>org.kar.karideo.WebLauncher</mainClass>
|
<mainClass>org.atriasoft.karideo.WebLauncher</mainClass>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>dev-mode</id>
|
||||||
|
<goals>
|
||||||
|
<goal>java</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>org.atriasoft.karideo.WebLauncherLocal</mainClass>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>generate-api</id>
|
||||||
|
<goals>
|
||||||
|
<goal>java</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>org.atriasoft.karideo.GenerateApi</mainClass>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<mainClass/>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Create the source bundle -->
|
<!-- Create the source bundle -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
<version>3.2.1</version>
|
<version>4.0.0-beta-1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>attach-sources</id>
|
<id>attach-sources</id>
|
||||||
@@ -95,10 +150,12 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.0.0-M5</version>
|
<version>3.2.5</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>3.7.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifest>
|
<manifest>
|
||||||
@@ -110,94 +167,21 @@
|
|||||||
</descriptorRefs>
|
</descriptorRefs>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Create coverage -->
|
|
||||||
<!--
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.jacoco</groupId>
|
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
|
||||||
<version>0.8.10</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>prepare-agent</id>
|
|
||||||
<goals>
|
|
||||||
<goal>prepare-agent</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>report</id>
|
|
||||||
<phase>test</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>report</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>jacoco-check</id>
|
|
||||||
<goals>
|
|
||||||
<goal>check</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<rules>
|
|
||||||
<rule>
|
|
||||||
<element>PACKAGE</element>
|
|
||||||
<limits>
|
|
||||||
<limit>
|
|
||||||
<counter>LINE</counter>
|
|
||||||
<value>COVEREDRATIO</value>
|
|
||||||
<minimum>0.50</minimum>
|
|
||||||
</limit>
|
|
||||||
</limits>
|
|
||||||
</rule>
|
|
||||||
</rules>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
-->
|
|
||||||
<!-- Java-doc generation for stand-alone site -->
|
<!-- Java-doc generation for stand-alone site -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>3.2.0</version>
|
<version>3.3.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<show>private</show>
|
<show>private</show>
|
||||||
<nohelp>true</nohelp>
|
<nohelp>true</nohelp>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>exec-maven-plugin</artifactId>
|
|
||||||
<version>3.1.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>exec-application</id>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>java</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<mainClass>org.kar.karideo.WebLauncher</mainClass>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<!-- Check the style of the code -->
|
<!-- Check the style of the code -->
|
||||||
<!--
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
|
||||||
<version>3.1.0</version>
|
|
||||||
<configuration>
|
|
||||||
<configLocation>CheckStyle.xml</configLocation>
|
|
||||||
<consoleOutput>true</consoleOutput>
|
|
||||||
<failOnViolation>true</failOnViolation>
|
|
||||||
<failsOnError>true</failsOnError>
|
|
||||||
<includeTestSourceDirectory>true</includeTestSourceDirectory>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>net.revelc.code.formatter</groupId>
|
<groupId>net.revelc.code.formatter</groupId>
|
||||||
<artifactId>formatter-maven-plugin</artifactId>
|
<artifactId>formatter-maven-plugin</artifactId>
|
||||||
<version>2.12.2</version>
|
<version>2.24.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<encoding>UTF-8</encoding>
|
<encoding>UTF-8</encoding>
|
||||||
<lineEnding>LF</lineEnding>
|
<lineEnding>LF</lineEnding>
|
||||||
@@ -221,7 +205,15 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
-->
|
<plugin>
|
||||||
|
<groupId>com.github.spotbugs</groupId>
|
||||||
|
<artifactId>spotbugs-maven-plugin</artifactId>
|
||||||
|
<version>4.8.5.0</version>
|
||||||
|
<configuration>
|
||||||
|
<includeFilterFile>spotbugs-security-include.xml</includeFilterFile>
|
||||||
|
<excludeFilterFile>spotbugs-security-exclude.xml</excludeFilterFile>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<!-- Generate Java-docs As Part Of Project Reports -->
|
<!-- Generate Java-docs As Part Of Project Reports -->
|
||||||
@@ -230,7 +222,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>3.2.0</version>
|
<version>3.3.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<show>public</show>
|
<show>public</show>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
245
back/pom.xml.versionsBackup
Normal file
245
back/pom.xml.versionsBackup
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.kar</groupId>
|
||||||
|
<artifactId>karideo</artifactId>
|
||||||
|
<version>0.3.0</version>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.version>3.1</maven.compiler.version>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<maven.dependency.version>3.1.1</maven.dependency.version>
|
||||||
|
</properties>
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>gitea</id>
|
||||||
|
<url>https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>kangaroo-and-rabbit</groupId>
|
||||||
|
<artifactId>archidata</artifactId>
|
||||||
|
<version>0.11.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-simple</artifactId>
|
||||||
|
<version>2.0.9</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
<version>2.16.1</version>
|
||||||
|
</dependency>
|
||||||
|
<!--
|
||||||
|
************************************************************
|
||||||
|
** TEST dependency **
|
||||||
|
************************************************************
|
||||||
|
-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>5.10.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>5.10.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<sourceDirectory>src</sourceDirectory>
|
||||||
|
<testSourceDirectory>test/src</testSourceDirectory>
|
||||||
|
<directory>${project.basedir}/out/maven/</directory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/resources</directory>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<testResources>
|
||||||
|
<testResource>
|
||||||
|
<directory>${basedir}/test/resources</directory>
|
||||||
|
</testResource>
|
||||||
|
</testResources>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven.compiler.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${maven.compiler.source}</source>
|
||||||
|
<target>${maven.compiler.target}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>1.4.0</version>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>org.kar.karideo.WebLauncher</mainClass>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<!-- Create the source bundle -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<version>3.2.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-sources</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<!-- junit results -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.0.0-M5</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>fully.qualified.MainClass</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<!-- Create coverage -->
|
||||||
|
<!--
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<version>0.8.10</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>prepare-agent</id>
|
||||||
|
<goals>
|
||||||
|
<goal>prepare-agent</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>report</id>
|
||||||
|
<phase>test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>report</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>jacoco-check</id>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<rules>
|
||||||
|
<rule>
|
||||||
|
<element>PACKAGE</element>
|
||||||
|
<limits>
|
||||||
|
<limit>
|
||||||
|
<counter>LINE</counter>
|
||||||
|
<value>COVEREDRATIO</value>
|
||||||
|
<minimum>0.50</minimum>
|
||||||
|
</limit>
|
||||||
|
</limits>
|
||||||
|
</rule>
|
||||||
|
</rules>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
-->
|
||||||
|
<!-- Java-doc generation for stand-alone site -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<configuration>
|
||||||
|
<show>private</show>
|
||||||
|
<nohelp>true</nohelp>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>exec-application</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>java</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>org.kar.karideo.WebLauncher</mainClass>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<!-- Check the style of the code -->
|
||||||
|
<!--
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<configuration>
|
||||||
|
<configLocation>CheckStyle.xml</configLocation>
|
||||||
|
<consoleOutput>true</consoleOutput>
|
||||||
|
<failOnViolation>true</failOnViolation>
|
||||||
|
<failsOnError>true</failsOnError>
|
||||||
|
<includeTestSourceDirectory>true</includeTestSourceDirectory>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>net.revelc.code.formatter</groupId>
|
||||||
|
<artifactId>formatter-maven-plugin</artifactId>
|
||||||
|
<version>2.12.2</version>
|
||||||
|
<configuration>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
<lineEnding>LF</lineEnding>
|
||||||
|
<configFile>Formatter.xml</configFile>
|
||||||
|
<directories>
|
||||||
|
<directory>src/</directory>
|
||||||
|
<directory>test/src</directory>
|
||||||
|
</directories>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.java</include>
|
||||||
|
</includes>
|
||||||
|
<excludes>
|
||||||
|
<exclude>module-info.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>validate</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
-->
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<!-- Generate Java-docs As Part Of Project Reports -->
|
||||||
|
<reporting>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<configuration>
|
||||||
|
<show>public</show>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</reporting>
|
||||||
|
</project>
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
org.kar.karideo.dataTmpFolder=/application/data/tmp
|
org.atriasoft.karideo.dataTmpFolder=/application/data/tmp
|
||||||
org.kar.karideo.dataTmpFolder=/application/data/media
|
org.atriasoft.karideo.dataTmpFolder=/application/data/media
|
||||||
org.kar.karideo.rest.oauth=http://192.168.1.156:21080/oauth/api/
|
org.atriasoft.karideo.rest.oauth=http://192.168.1.156:21080/oauth/api/
|
||||||
org.kar.karideo.db.host=1992.156.1.156
|
org.atriasoft.karideo.db.host=1992.156.1.156
|
||||||
org.kar.karideo.db.port=20306
|
org.atriasoft.karideo.db.port=20306
|
||||||
org.kar.karideo.db.login=root
|
org.atriasoft.karideo.db.login=root
|
||||||
org.kar.karideo.db.port=klkhj456gkgtkhjgvkujfhjgkjhgsdfhb3467465fgdhdesfgh
|
org.atriasoft.karideo.db.port=klkhj456gkgtkhjgvkujfhjgkjhgsdfhb3467465fgdhdesfgh
|
||||||
org.kar.karideo.db.name=karideo
|
org.atriasoft.karideo.db.name=karideo
|
||||||
org.kar.karideo.address=http://0.0.0.0:18080/karideo/api/
|
org.atriasoft.karideo.address=http://0.0.0.0:18080/karideo/api/
|
||||||
|
|||||||
17
back/src/org/atriasoft/karideo/GenerateApi.java
Normal file
17
back/src/org/atriasoft/karideo/GenerateApi.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package org.atriasoft.karideo;
|
||||||
|
|
||||||
|
import org.atriasoft.karideo.migration.Initialization;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class GenerateApi {
|
||||||
|
private final static Logger LOGGER = LoggerFactory.getLogger(GenerateApi.class);
|
||||||
|
|
||||||
|
private GenerateApi() {}
|
||||||
|
|
||||||
|
public static void main(final String[] args) throws Exception {
|
||||||
|
LOGGER.info("Generate API");
|
||||||
|
Initialization.generateObjects();
|
||||||
|
LOGGER.info("STOP the REST server.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,50 +1,53 @@
|
|||||||
package org.kar.karideo;
|
package org.atriasoft.karideo;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import java.util.logging.LogManager;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.UpdateJwtPublicKey;
|
||||||
|
import org.atriasoft.archidata.api.DataResource;
|
||||||
|
import org.atriasoft.archidata.catcher.GenericCatcher;
|
||||||
|
import org.atriasoft.archidata.cron.CronScheduler;
|
||||||
|
import org.atriasoft.archidata.db.DbConfig;
|
||||||
|
import org.atriasoft.archidata.filter.CORSFilter;
|
||||||
|
import org.atriasoft.archidata.filter.OptionFilter;
|
||||||
|
import org.atriasoft.archidata.migration.MigrationEngine;
|
||||||
|
import org.atriasoft.archidata.tools.ConfigBaseVariable;
|
||||||
|
import org.atriasoft.archidata.tools.ContextGenericTools;
|
||||||
|
import org.atriasoft.karideo.api.Front;
|
||||||
|
import org.atriasoft.karideo.api.HealthCheck;
|
||||||
|
import org.atriasoft.karideo.api.MediaResource;
|
||||||
|
import org.atriasoft.karideo.api.SeasonResource;
|
||||||
|
import org.atriasoft.karideo.api.SeriesResource;
|
||||||
|
import org.atriasoft.karideo.api.TypeResource;
|
||||||
|
import org.atriasoft.karideo.api.UserMediaAdvancementResource;
|
||||||
|
import org.atriasoft.karideo.api.UserResource;
|
||||||
|
import org.atriasoft.karideo.filter.KarideoAuthenticationFilter;
|
||||||
|
import org.atriasoft.karideo.job.BackupJob;
|
||||||
|
import org.atriasoft.karideo.migration.Initialization;
|
||||||
import org.glassfish.grizzly.http.server.HttpServer;
|
import org.glassfish.grizzly.http.server.HttpServer;
|
||||||
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
|
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
|
||||||
import org.glassfish.jersey.jackson.JacksonFeature;
|
import org.glassfish.jersey.jackson.JacksonFeature;
|
||||||
import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
||||||
import org.glassfish.jersey.server.ResourceConfig;
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
import org.kar.archidata.GlobalConfiguration;
|
import org.glassfish.jersey.server.validation.ValidationFeature;
|
||||||
import org.kar.archidata.UpdateJwtPublicKey;
|
|
||||||
import org.kar.archidata.api.DataResource;
|
|
||||||
import org.kar.archidata.catcher.ExceptionCatcher;
|
|
||||||
import org.kar.archidata.catcher.FailExceptionCatcher;
|
|
||||||
import org.kar.archidata.catcher.InputExceptionCatcher;
|
|
||||||
import org.kar.archidata.catcher.SystemExceptionCatcher;
|
|
||||||
import org.kar.archidata.db.DBConfig;
|
|
||||||
import org.kar.archidata.filter.CORSFilter;
|
|
||||||
import org.kar.archidata.filter.OptionFilter;
|
|
||||||
import org.kar.archidata.migration.MigrationEngine;
|
|
||||||
import org.kar.archidata.tools.ConfigBaseVariable;
|
|
||||||
import org.kar.karideo.api.Front;
|
|
||||||
import org.kar.karideo.api.HealthCheck;
|
|
||||||
import org.kar.karideo.api.SeasonResource;
|
|
||||||
import org.kar.karideo.api.SeriesResource;
|
|
||||||
import org.kar.karideo.api.TypeResource;
|
|
||||||
import org.kar.karideo.api.UserMediaAdvancementResource;
|
|
||||||
import org.kar.karideo.api.UserResource;
|
|
||||||
import org.kar.karideo.api.VideoResource;
|
|
||||||
import org.kar.karideo.filter.KarideoAuthenticationFilter;
|
|
||||||
import org.kar.karideo.migration.Initialization;
|
|
||||||
import org.kar.karideo.migration.Migration20230810;
|
|
||||||
import org.kar.karideo.migration.Migration20231015;
|
|
||||||
import org.kar.karideo.migration.Migration20231126;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.slf4j.bridge.SLF4JBridgeHandler;
|
||||||
|
|
||||||
import jakarta.ws.rs.core.UriBuilder;
|
import jakarta.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
public class WebLauncher {
|
public class WebLauncher {
|
||||||
final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class);
|
final static Logger LOGGER = LoggerFactory.getLogger(WebLauncher.class);
|
||||||
public static DBConfig dbConfig;
|
|
||||||
protected UpdateJwtPublicKey keyUpdater = null;
|
protected UpdateJwtPublicKey keyUpdater = null;
|
||||||
protected HttpServer server = null;
|
protected HttpServer server = null;
|
||||||
|
protected CronScheduler scheduler = null;
|
||||||
|
|
||||||
public WebLauncher() {
|
public WebLauncher() {
|
||||||
|
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
||||||
ConfigBaseVariable.bdDatabase = "karideo";
|
ConfigBaseVariable.bdDatabase = "karideo";
|
||||||
|
this.scheduler = new CronScheduler();
|
||||||
|
this.scheduler.setGracePeriodMinutes(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static URI getBaseURI() {
|
private static URI getBaseURI() {
|
||||||
@@ -57,16 +60,17 @@ public class WebLauncher {
|
|||||||
WebLauncher.LOGGER.info("Add initialization");
|
WebLauncher.LOGGER.info("Add initialization");
|
||||||
migrationEngine.setInit(new Initialization());
|
migrationEngine.setInit(new Initialization());
|
||||||
WebLauncher.LOGGER.info("Add migration since last version");
|
WebLauncher.LOGGER.info("Add migration since last version");
|
||||||
migrationEngine.add(new Migration20230810());
|
// migrationEngine.add(new Migration20250928());
|
||||||
migrationEngine.add(new Migration20231015());
|
|
||||||
migrationEngine.add(new Migration20231126());
|
|
||||||
//migrationEngine.add(new Migration20231126());
|
|
||||||
WebLauncher.LOGGER.info("Migrate the DB [START]");
|
WebLauncher.LOGGER.info("Migrate the DB [START]");
|
||||||
migrationEngine.migrateWaitAdmin(GlobalConfiguration.dbConfig);
|
migrationEngine.migrateWaitAdmin(new DbConfig());
|
||||||
WebLauncher.LOGGER.info("Migrate the DB [STOP]");
|
WebLauncher.LOGGER.info("Migrate the DB [STOP]");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(final String[] args) throws Exception {
|
public static void main(final String[] args) throws Exception {
|
||||||
|
// Loop-back of logger JDK logging API to SLF4J
|
||||||
|
LogManager.getLogManager().reset();
|
||||||
|
SLF4JBridgeHandler.install();
|
||||||
|
|
||||||
WebLauncher.LOGGER.info("[START] application wake UP");
|
WebLauncher.LOGGER.info("[START] application wake UP");
|
||||||
final WebLauncher launcher = new WebLauncher();
|
final WebLauncher launcher = new WebLauncher();
|
||||||
launcher.migrateDB();
|
launcher.migrateDB();
|
||||||
@@ -78,7 +82,7 @@ public class WebLauncher {
|
|||||||
WebLauncher.LOGGER.info("STOP the REST server");
|
WebLauncher.LOGGER.info("STOP the REST server");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process() throws InterruptedException {
|
public void process() throws Exception {
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
// Configure resources
|
// Configure resources
|
||||||
@@ -94,29 +98,32 @@ public class WebLauncher {
|
|||||||
// global authentication system
|
// global authentication system
|
||||||
rc.register(KarideoAuthenticationFilter.class);
|
rc.register(KarideoAuthenticationFilter.class);
|
||||||
// register exception catcher
|
// register exception catcher
|
||||||
rc.register(InputExceptionCatcher.class);
|
GenericCatcher.addAll(rc);
|
||||||
rc.register(SystemExceptionCatcher.class);
|
|
||||||
rc.register(FailExceptionCatcher.class);
|
|
||||||
rc.register(ExceptionCatcher.class);
|
|
||||||
// add default resource:
|
// add default resource:
|
||||||
rc.register(UserResource.class);
|
rc.register(UserResource.class);
|
||||||
rc.register(SeriesResource.class);
|
rc.register(SeriesResource.class);
|
||||||
rc.register(DataResource.class);
|
rc.register(DataResource.class);
|
||||||
rc.register(SeasonResource.class);
|
rc.register(SeasonResource.class);
|
||||||
rc.register(TypeResource.class);
|
rc.register(TypeResource.class);
|
||||||
rc.register(VideoResource.class);
|
rc.register(MediaResource.class);
|
||||||
rc.register(UserMediaAdvancementResource.class);
|
rc.register(UserMediaAdvancementResource.class);
|
||||||
|
|
||||||
rc.register(HealthCheck.class);
|
rc.register(HealthCheck.class);
|
||||||
rc.register(Front.class);
|
rc.register(Front.class);
|
||||||
|
ContextGenericTools.addJsr310(rc);
|
||||||
// add jackson to be discover when we are ins stand-alone server
|
// add jackson to be discover when we are ins stand-alone server
|
||||||
rc.register(JacksonFeature.class);
|
rc.register(JacksonFeature.class);
|
||||||
|
// enable jersey specific validations (@Valid)
|
||||||
|
rc.register(ValidationFeature.class);
|
||||||
// enable this to show low level request
|
// enable this to show low level request
|
||||||
//rc.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER, Level.WARNING.getName());
|
// rc.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER, Level.WARNING.getName());
|
||||||
|
|
||||||
this.server = GrizzlyHttpServerFactory.createHttpServer(getBaseURI(), rc);
|
this.server = GrizzlyHttpServerFactory.createHttpServer(getBaseURI(), rc);
|
||||||
final HttpServer serverLink = this.server;
|
final HttpServer serverLink = this.server;
|
||||||
|
// for (final NetworkListener listener : serverLink.getListeners()) {
|
||||||
|
// listener.getKeepAlive().setIdleTimeoutInSeconds(30); // Set idle timeout
|
||||||
|
// listener.getKeepAlive().setMaxRequestsCount(80); // Set request timeout
|
||||||
|
// }
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
|
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -131,6 +138,14 @@ public class WebLauncher {
|
|||||||
this.keyUpdater = new UpdateJwtPublicKey();
|
this.keyUpdater = new UpdateJwtPublicKey();
|
||||||
this.keyUpdater.start();
|
this.keyUpdater.start();
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
// start generic scheduler ...
|
||||||
|
// ===================================================================
|
||||||
|
this.scheduler.addTask("backup", "0 0 * * *", new BackupJob());
|
||||||
|
this.scheduler.start();
|
||||||
|
// execute a backup before start...
|
||||||
|
new BackupJob().run();
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
// run JERSEY
|
// run JERSEY
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
@@ -148,6 +163,10 @@ public class WebLauncher {
|
|||||||
this.server.shutdownNow();
|
this.server.shutdownNow();
|
||||||
this.server = null;
|
this.server = null;
|
||||||
}
|
}
|
||||||
|
if (this.scheduler != null) {
|
||||||
|
this.scheduler.stop();
|
||||||
|
this.scheduler = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopOther() {
|
public void stopOther() {
|
||||||
@@ -1,16 +1,26 @@
|
|||||||
|
|
||||||
package org.kar.karideo;
|
package org.atriasoft.karideo;
|
||||||
|
|
||||||
import org.kar.archidata.tools.ConfigBaseVariable;
|
import java.util.logging.LogManager;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.tools.ConfigBaseVariable;
|
||||||
|
import org.atriasoft.karideo.migration.Initialization;
|
||||||
|
import org.atriasoft.karideo.util.ConfigVariable;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.slf4j.bridge.SLF4JBridgeHandler;
|
||||||
|
|
||||||
public class WebLauncherLocal extends WebLauncher {
|
public class WebLauncherLocal extends WebLauncher {
|
||||||
private final static Logger LOGGER = LoggerFactory.getLogger(WebLauncherLocal.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(WebLauncherLocal.class);
|
||||||
|
|
||||||
private WebLauncherLocal() {}
|
private WebLauncherLocal() {}
|
||||||
|
|
||||||
public static void main(final String[] args) throws InterruptedException {
|
public static void main(final String[] args) throws Exception {
|
||||||
|
// Loop-back of logger JDK logging API to SLF4J
|
||||||
|
LogManager.getLogManager().reset();
|
||||||
|
SLF4JBridgeHandler.install();
|
||||||
|
// Generate the APIs in type-script
|
||||||
|
Initialization.generateObjects();
|
||||||
final WebLauncherLocal launcher = new WebLauncherLocal();
|
final WebLauncherLocal launcher = new WebLauncherLocal();
|
||||||
launcher.process();
|
launcher.process();
|
||||||
LOGGER.info("end-configure the server & wait finish process:");
|
LOGGER.info("end-configure the server & wait finish process:");
|
||||||
@@ -19,11 +29,15 @@ public class WebLauncherLocal extends WebLauncher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process() throws InterruptedException {
|
public void process() throws Exception {
|
||||||
if (true) {
|
if (true) {
|
||||||
// for local test:
|
// for local test:
|
||||||
ConfigBaseVariable.apiAdress = "http://0.0.0.0:18080/karideo/api/";
|
ConfigBaseVariable.apiAdress = "http://0.0.0.0:18080/karideo/api/";
|
||||||
ConfigBaseVariable.dbPort = "3906";
|
ConfigBaseVariable.testMode = "true";
|
||||||
|
ConfigBaseVariable.dbType = "mongo";
|
||||||
|
}
|
||||||
|
if (ConfigVariable.isInitWithBackup()) {
|
||||||
|
Initialization.initializeWithBackup();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
super.migrateDB();
|
super.migrateDB();
|
||||||
502
back/src/org/atriasoft/karideo/api/DataResource.java
Normal file
502
back/src/org/atriasoft/karideo/api/DataResource.java
Normal file
@@ -0,0 +1,502 @@
|
|||||||
|
package org.atriasoft.karideo.api;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiInputOptional;
|
||||||
|
import org.atriasoft.archidata.annotation.security.PermitTokenInURI;
|
||||||
|
import org.atriasoft.archidata.api.MediaStreamer;
|
||||||
|
import org.atriasoft.archidata.dataAccess.DataAccess;
|
||||||
|
import org.atriasoft.archidata.dataAccess.QueryCondition;
|
||||||
|
import org.atriasoft.archidata.dataAccess.options.Condition;
|
||||||
|
import org.atriasoft.archidata.exception.FailException;
|
||||||
|
import org.atriasoft.archidata.filter.GenericContext;
|
||||||
|
import org.atriasoft.archidata.model.Data;
|
||||||
|
import org.atriasoft.archidata.tools.ConfigBaseVariable;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.HeaderParam;
|
||||||
|
import jakarta.ws.rs.InternalServerErrorException;
|
||||||
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.QueryParam;
|
||||||
|
import jakarta.ws.rs.core.CacheControl;
|
||||||
|
import jakarta.ws.rs.core.Context;
|
||||||
|
import jakarta.ws.rs.core.HttpHeaders;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import jakarta.ws.rs.core.SecurityContext;
|
||||||
|
import jakarta.ws.rs.core.StreamingOutput;
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/35367113/jersey-webservice-scalable-approach-to-download-file-and-reply-to-client
|
||||||
|
// https://gist.github.com/aitoroses/4f7a2b197b732a6a691d
|
||||||
|
|
||||||
|
@Path("/data")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public class DataResource {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(DataResource.class);
|
||||||
|
private final static int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
|
||||||
|
private final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
|
||||||
|
/** Upload some datas */
|
||||||
|
private static long tmpFolderId = 1;
|
||||||
|
|
||||||
|
private static void createFolder(final String path) throws IOException {
|
||||||
|
if (!Files.exists(Paths.get(path))) {
|
||||||
|
Files.createDirectories(Paths.get(path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getTmpDataId() {
|
||||||
|
return tmpFolderId++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTmpFileInData(final long tmpFolderId) {
|
||||||
|
final String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId;
|
||||||
|
try {
|
||||||
|
createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFileDataOld(final UUID uuid) {
|
||||||
|
final String stringUUID = uuid.toString();
|
||||||
|
final String part1 = stringUUID.substring(0, 2);
|
||||||
|
final String part2 = stringUUID.substring(2, 4);
|
||||||
|
final String part3 = stringUUID.substring(4);
|
||||||
|
final String finalPath = part1 + File.separator + part2;
|
||||||
|
String filePath = ConfigBaseVariable.getMediaDataFolder() + "_uuid" + File.separator + finalPath + File.separator;
|
||||||
|
try {
|
||||||
|
createFolder(filePath);
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
filePath += part3;
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFileData(final ObjectId oid) {
|
||||||
|
final String stringOid = oid.toHexString();
|
||||||
|
String dir1 = stringOid.substring(0, 2);
|
||||||
|
String dir2 = stringOid.substring(2, 4);
|
||||||
|
String dir3 = stringOid.substring(4, 6);
|
||||||
|
try {
|
||||||
|
final MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||||
|
final byte[] hashBytes = digest.digest(oid.toByteArray());
|
||||||
|
dir1 = String.format("%02x", hashBytes[0]);
|
||||||
|
dir2 = String.format("%02x", hashBytes[1]);
|
||||||
|
dir3 = String.format("%02x", hashBytes[2]);
|
||||||
|
} catch (final NoSuchAlgorithmException ex) {
|
||||||
|
LOGGER.error("Fail to generate the hash of the objectId ==> ise direct value ... {}", ex.getMessage());
|
||||||
|
}
|
||||||
|
final String finalPath = dir1 + File.separator + dir2 + File.separator + dir3;
|
||||||
|
String filePath = ConfigBaseVariable.getMediaDataFolder() + "_oid" + File.separator + finalPath + File.separator;
|
||||||
|
try {
|
||||||
|
createFolder(filePath);
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
filePath += stringOid;
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFileMetaData(final ObjectId oid) {
|
||||||
|
return getFileData(oid) + ".json";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data getWithSha512(final String sha512) {
|
||||||
|
LOGGER.info("find sha512 = {}", sha512);
|
||||||
|
try {
|
||||||
|
return DataAccess.getWhere(Data.class, new Condition(new QueryCondition("sha512", "=", sha512)));
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data getWithId(final long id) {
|
||||||
|
LOGGER.info("find id = {}", id);
|
||||||
|
try {
|
||||||
|
return DataAccess.get(Data.class, id);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getMimeType(final String extension) throws IOException {
|
||||||
|
return switch (extension.toLowerCase()) {
|
||||||
|
case "jpg", "jpeg" -> "image/jpeg";
|
||||||
|
case "png" -> "image/png";
|
||||||
|
case "webp" -> "image/webp";
|
||||||
|
case "mka" -> "audio/x-matroska";
|
||||||
|
case "mkv" -> "video/x-matroska";
|
||||||
|
case "webm" -> "video/webm";
|
||||||
|
default -> throw new IOException("Can not find the mime type of data input: '" + extension + "'");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data createNewData(final long tmpUID, final String originalFileName, final String sha512) throws IOException {
|
||||||
|
// determine mime type:
|
||||||
|
Data injectedData = new Data();
|
||||||
|
String mimeType = "";
|
||||||
|
final String extension = originalFileName.substring(originalFileName.lastIndexOf('.') + 1);
|
||||||
|
mimeType = getMimeType(extension);
|
||||||
|
injectedData.mimeType = mimeType;
|
||||||
|
injectedData.sha512 = sha512;
|
||||||
|
final String tmpPath = getTmpFileInData(tmpUID);
|
||||||
|
injectedData.size = Files.size(Paths.get(tmpPath));
|
||||||
|
|
||||||
|
try {
|
||||||
|
injectedData = DataAccess.insert(injectedData);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final String mediaPath = getFileData(injectedData.oid);
|
||||||
|
LOGGER.info("src = {}", tmpPath);
|
||||||
|
LOGGER.info("dst = {}", mediaPath);
|
||||||
|
Files.move(Paths.get(tmpPath), Paths.get(mediaPath), StandardCopyOption.ATOMIC_MOVE);
|
||||||
|
LOGGER.info("Move done");
|
||||||
|
return injectedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void modeFileOldModelToNewModel(final UUID uuid, final ObjectId oid) throws IOException {
|
||||||
|
String mediaCurentPath = getFileDataOld(uuid);
|
||||||
|
String mediaDestPath = getFileData(oid);
|
||||||
|
LOGGER.info("src = {}", mediaCurentPath);
|
||||||
|
LOGGER.info("dst = {}", mediaDestPath);
|
||||||
|
if (Files.exists(Paths.get(mediaCurentPath))) {
|
||||||
|
LOGGER.info("move: {} ==> {}", mediaCurentPath, mediaDestPath);
|
||||||
|
Files.move(Paths.get(mediaCurentPath), Paths.get(mediaDestPath), StandardCopyOption.ATOMIC_MOVE);
|
||||||
|
}
|
||||||
|
// Move old meta-data...
|
||||||
|
mediaCurentPath = mediaCurentPath.substring(mediaCurentPath.length() - 4) + "meta.json";
|
||||||
|
mediaDestPath = mediaCurentPath.substring(mediaDestPath.length() - 4) + "meta.json";
|
||||||
|
if (Files.exists(Paths.get(mediaCurentPath))) {
|
||||||
|
LOGGER.info("moveM: {} ==> {}", mediaCurentPath, mediaDestPath);
|
||||||
|
Files.move(Paths.get(mediaCurentPath), Paths.get(mediaDestPath), StandardCopyOption.ATOMIC_MOVE);
|
||||||
|
}
|
||||||
|
LOGGER.info("Move done");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String saveTemporaryFile(final InputStream uploadedInputStream, final long idData) throws FailException {
|
||||||
|
return saveFile(uploadedInputStream, DataResource.getTmpFileInData(idData));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeTemporaryFile(final long idData) {
|
||||||
|
final String filepath = DataResource.getTmpFileInData(idData);
|
||||||
|
if (Files.exists(Paths.get(filepath))) {
|
||||||
|
try {
|
||||||
|
Files.delete(Paths.get(filepath));
|
||||||
|
} catch (final IOException e) {
|
||||||
|
LOGGER.info("can not delete temporary file : {}", Paths.get(filepath));
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// save uploaded file to a defined location on the server
|
||||||
|
static String saveFile(final InputStream uploadedInputStream, final String serverLocation) throws FailException {
|
||||||
|
String out = "";
|
||||||
|
MessageDigest md = null;
|
||||||
|
try (OutputStream outpuStream = new FileOutputStream(new File(serverLocation))) {
|
||||||
|
md = MessageDigest.getInstance("SHA-512");
|
||||||
|
outpuStream.flush();
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Can not write in temporary file", ex);
|
||||||
|
} catch (final NoSuchAlgorithmException ex) {
|
||||||
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Can not find sha512 algorithms", ex);
|
||||||
|
}
|
||||||
|
if (md != null) {
|
||||||
|
try (OutputStream outpuStream = new FileOutputStream(new File(serverLocation))) {
|
||||||
|
int read = 0;
|
||||||
|
final byte[] bytes = new byte[CHUNK_SIZE_IN];
|
||||||
|
while ((read = uploadedInputStream.read(bytes)) != -1) {
|
||||||
|
// logger.info("write {}", read);
|
||||||
|
md.update(bytes, 0, read);
|
||||||
|
outpuStream.write(bytes, 0, read);
|
||||||
|
}
|
||||||
|
LOGGER.info("Flush input stream ... {}", serverLocation);
|
||||||
|
outpuStream.flush();
|
||||||
|
// create the end of sha512
|
||||||
|
final byte[] sha512Digest = md.digest();
|
||||||
|
// convert in hexadecimal
|
||||||
|
out = bytesToHex(sha512Digest);
|
||||||
|
uploadedInputStream.close();
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Can not write in temporary file", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String bytesToHex(final byte[] bytes) {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
for (final byte b : bytes) {
|
||||||
|
sb.append(String.format("%02x", b));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data getSmall(final ObjectId oid) {
|
||||||
|
try {
|
||||||
|
return DataAccess.get(Data.class, oid);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/upload/")
|
||||||
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Operation(description = "Insert a new data in the data environment", tags = "SYSTEM")
|
||||||
|
public void uploadFile(@Context final SecurityContext sc, @FormDataParam("file") final InputStream fileInputStream, @FormDataParam("file") final FormDataContentDisposition fileMetaData)
|
||||||
|
throws FailException {
|
||||||
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
LOGGER.info("===================================================");
|
||||||
|
LOGGER.info("== DATA uploadFile {}", (gc == null ? "null" : gc.userByToken));
|
||||||
|
LOGGER.info("===================================================");
|
||||||
|
// public NodeSmall uploadFile(final FormDataMultiPart form) {
|
||||||
|
LOGGER.info("Upload file: ");
|
||||||
|
final String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId++;
|
||||||
|
try {
|
||||||
|
createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Impossible to create the folder in the server", ex);
|
||||||
|
}
|
||||||
|
saveFile(fileInputStream, filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{oid}")
|
||||||
|
@PermitTokenInURI
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
|
@Operation(description = "Get back some data from the data environment", tags = "SYSTEM")
|
||||||
|
public Response retrieveDataId(@Context final SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) final String token, @HeaderParam("Range") final String range,
|
||||||
|
@PathParam("oid") final ObjectId oid) throws FailException {
|
||||||
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
// logger.info("===================================================");
|
||||||
|
LOGGER.info("== DATA retrieveDataId ? oid={} user={}", oid, (gc == null ? "null" : gc.userByToken));
|
||||||
|
// logger.info("===================================================");
|
||||||
|
final Data value = getSmall(oid);
|
||||||
|
if (value == null) {
|
||||||
|
return Response.status(404).entity("media NOT FOUND: " + oid).type("text/plain").build();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return buildStream(getFileData(oid), range, value.mimeType == null ? "application/octet-stream" : value.mimeType);
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to build output stream", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("thumbnail/{oid}")
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@PermitTokenInURI
|
||||||
|
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
|
@Operation(description = "Get a thumbnail of from the data environment (if resize is possible)", tags = "SYSTEM")
|
||||||
|
// @CacheMaxAge(time = 10, unit = TimeUnit.DAYS)
|
||||||
|
public Response retrieveDataThumbnailId(@Context final SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) final String token, @HeaderParam("Range") final String range,
|
||||||
|
@PathParam("oid") final ObjectId oid) throws FailException {
|
||||||
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
LOGGER.info("===================================================");
|
||||||
|
LOGGER.info("== DATA retrieveDataThumbnailId ? {}", (gc == null ? "null" : gc.userByToken));
|
||||||
|
LOGGER.info("===================================================");
|
||||||
|
final Data value = getSmall(oid);
|
||||||
|
if (value == null) {
|
||||||
|
return Response.status(404).entity("media NOT FOUND: " + oid).type("text/plain").build();
|
||||||
|
}
|
||||||
|
final String filePathName = getFileData(oid);
|
||||||
|
final File inputFile = new File(filePathName);
|
||||||
|
if (!inputFile.exists()) {
|
||||||
|
return Response.status(404).entity("{\"error\":\"media Does not exist: " + oid + "\"}").type("application/json").build();
|
||||||
|
}
|
||||||
|
if (value.mimeType.contentEquals("image/jpeg") || value.mimeType.contentEquals("image/png")
|
||||||
|
// || value.mimeType.contentEquals("image/webp")
|
||||||
|
) {
|
||||||
|
// reads input image
|
||||||
|
BufferedImage inputImage;
|
||||||
|
try {
|
||||||
|
inputImage = ImageIO.read(inputFile);
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to READ the image", ex);
|
||||||
|
}
|
||||||
|
LOGGER.info("input size image: {}x{} type={}", inputImage.getWidth(), inputImage.getHeight(), inputImage.getType());
|
||||||
|
final int scaledWidth = ConfigBaseVariable.getThumbnailWidth();
|
||||||
|
final int scaledHeight = (int) ((float) inputImage.getHeight() / (float) inputImage.getWidth() * scaledWidth);
|
||||||
|
// creates output image
|
||||||
|
final BufferedImage outputImage = new BufferedImage(scaledWidth, scaledHeight, inputImage.getType());
|
||||||
|
|
||||||
|
// scales the input image to the output image
|
||||||
|
final Graphics2D g2d = outputImage.createGraphics();
|
||||||
|
LOGGER.info("output size image: {}x{}", scaledWidth, scaledHeight);
|
||||||
|
g2d.drawImage(inputImage, 0, 0, scaledWidth, scaledHeight, null);
|
||||||
|
g2d.dispose();
|
||||||
|
// create the output stream:
|
||||||
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
ImageIO.write(outputImage, ConfigBaseVariable.getThumbnailFormat(), baos);
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return Response.status(500).entity("Internal Error: resize fail: " + e.getMessage()).type("text/plain").build();
|
||||||
|
}
|
||||||
|
final byte[] imageData = baos.toByteArray();
|
||||||
|
LOGGER.info("output length {}", imageData.length);
|
||||||
|
if (imageData.length == 0) {
|
||||||
|
LOGGER.error("Fail to convert image... Availlable format:");
|
||||||
|
for (final String data : ImageIO.getWriterFormatNames()) {
|
||||||
|
LOGGER.error(" - {}", data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final Response.ResponseBuilder out = Response.ok(imageData).header(HttpHeaders.CONTENT_LENGTH, imageData.length);
|
||||||
|
try {
|
||||||
|
out.type(getMimeType(ConfigBaseVariable.getThumbnailFormat()));
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to convert mime type of " + ConfigBaseVariable.getThumbnailFormat(), ex);
|
||||||
|
}
|
||||||
|
// TODO: move this in a decorator !!!
|
||||||
|
final CacheControl cc = new CacheControl();
|
||||||
|
cc.setMaxAge(3600);
|
||||||
|
cc.setNoCache(false);
|
||||||
|
out.cacheControl(cc);
|
||||||
|
return out.build();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return buildStream(filePathName, range, value.mimeType);
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to build output stream", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{oid}/{name}")
|
||||||
|
@PermitTokenInURI
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
|
@Operation(description = "Get back some data from the data environment (with a beautiful name (permit download with basic name)", tags = "SYSTEM")
|
||||||
|
public Response retrieveDataFull(@Context final SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) final String token, @ApiInputOptional @HeaderParam("Range") final String range,
|
||||||
|
@PathParam("oid") final ObjectId oid, @PathParam("name") final String name) throws Exception {
|
||||||
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
// logger.info("===================================================");
|
||||||
|
LOGGER.info("== DATA retrieveDataFull ? id={} user={}", oid, (gc == null ? "null" : gc.userByToken));
|
||||||
|
// logger.info("===================================================");
|
||||||
|
final Data value = getSmall(oid);
|
||||||
|
if (value == null) {
|
||||||
|
return Response.status(404).entity("media NOT FOUND: " + oid).type("text/plain").build();
|
||||||
|
}
|
||||||
|
return buildStream(getFileData(oid), range, value.mimeType == null ? "application/octet-stream" : value.mimeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adapted from http://stackoverflow.com/questions/12768812/video-streaming-to-ipad-does-not-work-with-tapestry5/12829541#12829541
|
||||||
|
*
|
||||||
|
* @param range range header
|
||||||
|
* @return Streaming output
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* @throws Exception IOException if an error occurs in streaming. */
|
||||||
|
private Response buildStream(final String filename, final String range, final String mimeType) throws FailException {
|
||||||
|
final File file = new File(filename);
|
||||||
|
// logger.info("request range : {}", range);
|
||||||
|
// range not requested : Firefox does not send range headers
|
||||||
|
if (range == null) {
|
||||||
|
final StreamingOutput output = new StreamingOutput() {
|
||||||
|
@Override
|
||||||
|
public void write(final OutputStream out) {
|
||||||
|
try (FileInputStream in = new FileInputStream(file)) {
|
||||||
|
final byte[] buf = new byte[1024 * 1024];
|
||||||
|
int len;
|
||||||
|
while ((len = in.read(buf)) != -1) {
|
||||||
|
try {
|
||||||
|
out.write(buf, 0, len);
|
||||||
|
out.flush();
|
||||||
|
// logger.info("---- wrote {} bytes file ----", len);
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
LOGGER.info("remote close connection");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
throw new InternalServerErrorException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
final Response.ResponseBuilder out = Response.ok(output).header(HttpHeaders.CONTENT_LENGTH, file.length());
|
||||||
|
if (mimeType != null) {
|
||||||
|
out.type(mimeType);
|
||||||
|
}
|
||||||
|
return out.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
final String[] ranges = range.split("=")[1].split("-");
|
||||||
|
final long from = Long.parseLong(ranges[0]);
|
||||||
|
|
||||||
|
// logger.info("request range : {}", ranges.length);
|
||||||
|
// Chunk media if the range upper bound is unspecified. Chrome, Opera sends "bytes=0-"
|
||||||
|
long to = CHUNK_SIZE + from;
|
||||||
|
if (ranges.length == 1) {
|
||||||
|
to = file.length() - 1;
|
||||||
|
} else if (to >= file.length()) {
|
||||||
|
to = file.length() - 1;
|
||||||
|
}
|
||||||
|
final String responseRange = String.format("bytes %d-%d/%d", from, to, file.length());
|
||||||
|
// LOGGER.info("responseRange: {}", responseRange);
|
||||||
|
try {
|
||||||
|
final RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||||
|
raf.seek(from);
|
||||||
|
|
||||||
|
final long len = to - from + 1;
|
||||||
|
final MediaStreamer streamer = new MediaStreamer(len, raf);
|
||||||
|
final Response.ResponseBuilder out = Response.ok(streamer).status(Response.Status.PARTIAL_CONTENT).header("Accept-Ranges", "bytes").header("Content-Range", responseRange)
|
||||||
|
.header(HttpHeaders.CONTENT_LENGTH, streamer.getLenth()).header(HttpHeaders.LAST_MODIFIED, new Date(file.lastModified()));
|
||||||
|
if (mimeType != null) {
|
||||||
|
out.type(mimeType);
|
||||||
|
}
|
||||||
|
return out.build();
|
||||||
|
} catch (final FileNotFoundException ex) {
|
||||||
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to find the required file.", ex);
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to access to the required file.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void undelete(final Long id) throws Exception {
|
||||||
|
DataAccess.unsetDelete(Data.class, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
package org.kar.karideo.api;
|
package org.atriasoft.karideo.api;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.api.FrontGeneric;
|
||||||
import org.kar.archidata.api.FrontGeneric;
|
|
||||||
|
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
|
|
||||||
import org.kar.karideo.util.ConfigVariable;
|
import org.atriasoft.karideo.util.ConfigVariable;
|
||||||
|
|
||||||
@Path("/front")
|
@Path("/front")
|
||||||
public class Front extends FrontGeneric {
|
public class Front extends FrontGeneric {
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
package org.kar.karideo.api;
|
package org.atriasoft.karideo.api;
|
||||||
|
|
||||||
import org.kar.archidata.exception.FailException;
|
import org.atriasoft.archidata.exception.FailException;
|
||||||
import org.kar.archidata.tools.ConfigBaseVariable;
|
import org.atriasoft.archidata.tools.ConfigBaseVariable;
|
||||||
import org.kar.archidata.tools.JWTWrapper;
|
import org.atriasoft.archidata.tools.JWTWrapper;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import jakarta.annotation.security.PermitAll;
|
import jakarta.annotation.security.PermitAll;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
@@ -18,11 +19,13 @@ import jakarta.ws.rs.core.Response;
|
|||||||
public class HealthCheck {
|
public class HealthCheck {
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(HealthCheck.class);
|
static final Logger LOGGER = LoggerFactory.getLogger(HealthCheck.class);
|
||||||
|
|
||||||
public record HealthResult(
|
public record HealthResult(String value) {
|
||||||
String value) {};
|
|
||||||
|
};
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@PermitAll
|
@PermitAll
|
||||||
|
@Operation(description = "Get the server state (health)", tags = "SYSTEM")
|
||||||
public HealthResult getHealth() throws FailException {
|
public HealthResult getHealth() throws FailException {
|
||||||
if (JWTWrapper.getPublicKeyJson() == null && !ConfigBaseVariable.getTestMode()) {
|
if (JWTWrapper.getPublicKeyJson() == null && !ConfigBaseVariable.getTestMode()) {
|
||||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Missing Jwt public token");
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Missing Jwt public token");
|
||||||
241
back/src/org/atriasoft/karideo/api/MediaResource.java
Normal file
241
back/src/org/atriasoft/karideo/api/MediaResource.java
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
package org.atriasoft.karideo.api;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiTypeScriptProgress;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.GroupUpdate;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.ValidGroup;
|
||||||
|
import org.atriasoft.archidata.api.DataResource;
|
||||||
|
import org.atriasoft.archidata.dataAccess.DBAccess;
|
||||||
|
import org.atriasoft.archidata.dataAccess.DataAccess;
|
||||||
|
import org.atriasoft.archidata.exception.FailException;
|
||||||
|
import org.atriasoft.archidata.exception.InputException;
|
||||||
|
import org.atriasoft.archidata.model.Data;
|
||||||
|
import org.atriasoft.archidata.tools.DataTools;
|
||||||
|
import org.atriasoft.karideo.model.Media;
|
||||||
|
import org.atriasoft.karideo.model.Season;
|
||||||
|
import org.atriasoft.karideo.model.Series;
|
||||||
|
import org.atriasoft.karideo.model.Type;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.DELETE;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.PUT;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
@Path("/media")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public class MediaResource {
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(MediaResource.class);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Operation(description = "Get all Media", tags = "GLOBAL")
|
||||||
|
public List<Media> gets() throws Exception {
|
||||||
|
return DataAccess.gets(Media.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{id}")
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Operation(description = "Get a specific Media with his ID", tags = "GLOBAL")
|
||||||
|
public Media get(@PathParam("id") final Long id) throws Exception {
|
||||||
|
return DataAccess.get(Media.class, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(description = "Modify a specific Media", tags = "GLOBAL")
|
||||||
|
public Media put(@PathParam("oid") final ObjectId oid, @Valid @ValidGroup(GroupUpdate.class) final Media media) throws Exception {
|
||||||
|
LOGGER.info("update video {} ==> '{}'", oid, media);
|
||||||
|
media.oid = oid;
|
||||||
|
DataAccess.update(media, oid);
|
||||||
|
return DataAccess.get(Media.class, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String multipartCorrection(final String data) {
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (data.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (data.contentEquals("null")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (data.contentEquals("undefined")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
|
@Operation(description = "Create a new Media", tags = "GLOBAL")
|
||||||
|
@ApiTypeScriptProgress
|
||||||
|
public Media uploadMedia( //
|
||||||
|
// @AsyncType(Long.class) @FormDataParam("universeId") String universeId, //
|
||||||
|
// @AsyncType(Long.class) @FormDataParam("typeId") String typeId, //
|
||||||
|
// @AsyncType(Long.class) @FormDataParam("seriesId") String seriesId, //
|
||||||
|
// @AsyncType(Long.class) @FormDataParam("season") String season, // value of the season ==> local add if needed
|
||||||
|
// @AsyncType(Long.class) @FormDataParam("episode") String episode, // value of the season ==> local add if needed
|
||||||
|
@FormDataParam("universeId") String universeId, //
|
||||||
|
@FormDataParam("typeId") String typeId, //
|
||||||
|
@FormDataParam("seriesId") String seriesId, //
|
||||||
|
@FormDataParam("season") String season, // value of the season ==> local add if needed
|
||||||
|
@FormDataParam("episode") String episode, // value of the season ==> local add if needed
|
||||||
|
@FormDataParam("title") String title, //
|
||||||
|
@FormDataParam("file") final InputStream fileInputStream, //
|
||||||
|
@FormDataParam("file") final FormDataContentDisposition fileMetaData //
|
||||||
|
) throws FailException {
|
||||||
|
try (DBAccess db = DBAccess.createInterface()) {
|
||||||
|
// correct input string stream :
|
||||||
|
final String fileName = multipartCorrection(fileMetaData.getFileName());
|
||||||
|
universeId = multipartCorrection(universeId);
|
||||||
|
final ObjectId universeOid = universeId != null ? new ObjectId(universeId) : null;
|
||||||
|
typeId = multipartCorrection(typeId);
|
||||||
|
final ObjectId typeOid = typeId != null ? new ObjectId(typeId) : null;
|
||||||
|
seriesId = multipartCorrection(seriesId);
|
||||||
|
final ObjectId seriesOid = seriesId != null ? new ObjectId(seriesId) : null;
|
||||||
|
season = multipartCorrection(season);
|
||||||
|
final Long seasonLong = season != null ? Long.parseLong(season) : null;
|
||||||
|
episode = multipartCorrection(episode);
|
||||||
|
title = multipartCorrection(title);
|
||||||
|
|
||||||
|
// todo: check if all remotes Id exist ...
|
||||||
|
|
||||||
|
// public NodeSmall uploadFile(final FormDataMultiPart form) {
|
||||||
|
LOGGER.info("Upload media file: {}", fileMetaData);
|
||||||
|
LOGGER.info(" - fileName: {}", fileName);
|
||||||
|
LOGGER.info(" - universe: {}", universeOid);
|
||||||
|
LOGGER.info(" - series: {}", seriesOid);
|
||||||
|
LOGGER.info(" - season: {}", seasonLong);
|
||||||
|
LOGGER.info(" - episode: {}", episode);
|
||||||
|
LOGGER.info(" - title: {}", title);
|
||||||
|
LOGGER.info(" - type: {}", typeId);
|
||||||
|
LOGGER.info(" - fileInputStream: {}", fileInputStream);
|
||||||
|
LOGGER.info(" - fileMetaData: {}", fileMetaData);
|
||||||
|
System.out.flush();
|
||||||
|
if (typeId == null) {
|
||||||
|
throw new InputException("typeId", "TypiId is not specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
final long tmpUID = DataResource.getTmpDataId();
|
||||||
|
final String sha512 = DataResource.saveTemporaryFile(fileInputStream, tmpUID);
|
||||||
|
Data data = DataTools.getWithSha512(db, sha512);
|
||||||
|
if (data == null) {
|
||||||
|
LOGGER.info("Need to add the data in the BDD ... ");
|
||||||
|
System.out.flush();
|
||||||
|
try {
|
||||||
|
data = DataTools.createNewData(db, tmpUID, fileName, sha512);
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
DataResource.removeTemporaryFile(tmpUID);
|
||||||
|
ex.printStackTrace();
|
||||||
|
throw new FailException("can not create input media (the data model has an internal error");
|
||||||
|
}
|
||||||
|
} else if (data != null && data.deleted != null && data.deleted) {
|
||||||
|
LOGGER.info("Data already exist but deleted");
|
||||||
|
System.out.flush();
|
||||||
|
DataTools.undelete(db, data.oid);
|
||||||
|
data.deleted = false;
|
||||||
|
} else {
|
||||||
|
LOGGER.info("Data already exist ... all good");
|
||||||
|
System.out.flush();
|
||||||
|
}
|
||||||
|
// Fist step: retieve all the Id of each parents:...
|
||||||
|
LOGGER.info("Find typeNode");
|
||||||
|
// check if id of type exist:
|
||||||
|
final Type typeNode = TypeResource.getId(typeOid);
|
||||||
|
if (typeNode == null) {
|
||||||
|
DataResource.removeTemporaryFile(tmpUID);
|
||||||
|
throw new InputException("typeId", "TypeId does not exist ...");
|
||||||
|
}
|
||||||
|
// check if id of type exist:
|
||||||
|
Series seriesNode = null;
|
||||||
|
if (seriesOid != null) {
|
||||||
|
seriesNode = SeriesResource.getId(seriesOid);
|
||||||
|
if (seriesNode == null) {
|
||||||
|
DataResource.removeTemporaryFile(tmpUID);
|
||||||
|
throw new InputException("seriesId", "seriesId does not exist ...");
|
||||||
|
}
|
||||||
|
if (!seriesNode.typeId.equals(typeNode.oid)) {
|
||||||
|
DataResource.removeTemporaryFile(tmpUID);
|
||||||
|
throw new InputException("seriesId", "seriesId object have not the correct parent... '" + seriesNode.typeId + "' != '" + typeNode.oid + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info(" ==> {}", seriesNode);
|
||||||
|
LOGGER.info("Find seasonNode");
|
||||||
|
// get uid of season:
|
||||||
|
Season seasonNode = null;
|
||||||
|
if (seriesNode == null && seasonLong != null) {
|
||||||
|
DataResource.removeTemporaryFile(tmpUID);
|
||||||
|
throw new InputException("season", "Season is set but no series is set !!");
|
||||||
|
}
|
||||||
|
if (season != null) {
|
||||||
|
seasonNode = SeasonResource.getOrCreate(season, seriesNode.oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info(" ==> {}", seasonNode);
|
||||||
|
LOGGER.info("add media");
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Media media = new Media();
|
||||||
|
media.name = title;
|
||||||
|
media.dataId = data.oid;
|
||||||
|
media.typeId = typeNode.oid;
|
||||||
|
media.seriesId = null;
|
||||||
|
if (seriesNode != null) {
|
||||||
|
media.seriesId = seriesNode.oid;
|
||||||
|
}
|
||||||
|
media.seasonId = null;
|
||||||
|
if (seasonNode != null) {
|
||||||
|
media.seasonId = seasonNode.oid;
|
||||||
|
}
|
||||||
|
media.episode = null;
|
||||||
|
if (episode != null && !episode.contentEquals("")) {
|
||||||
|
media.episode = Integer.parseInt(episode);
|
||||||
|
}
|
||||||
|
final Media out = db.insert(media);
|
||||||
|
LOGGER.info("Generate new media {}", out);
|
||||||
|
return out;
|
||||||
|
} catch (final SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
LOGGER.error("Catch error: {}", ex.getMessage());
|
||||||
|
throw new FailException("Catch SQLerror ==> check server logs");
|
||||||
|
} finally {
|
||||||
|
DataResource.removeTemporaryFile(tmpUID);
|
||||||
|
}
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
LOGGER.error("Catch an unexpected error ... {} ", ex.getMessage());
|
||||||
|
ex.printStackTrace();
|
||||||
|
throw new FailException("Catch Exception ==> check server logs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Operation(description = "Remove a specific Media", tags = "GLOBAL")
|
||||||
|
public void remove(@PathParam("oid") final ObjectId id) throws Exception {
|
||||||
|
DataAccess.delete(Media.class, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
97
back/src/org/atriasoft/karideo/api/SeasonResource.java
Normal file
97
back/src/org/atriasoft/karideo/api/SeasonResource.java
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package org.atriasoft.karideo.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.checker.GroupCreate;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.GroupUpdate;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.ValidGroup;
|
||||||
|
import org.atriasoft.archidata.dataAccess.DataAccess;
|
||||||
|
import org.atriasoft.archidata.dataAccess.QueryAnd;
|
||||||
|
import org.atriasoft.archidata.dataAccess.QueryCondition;
|
||||||
|
import org.atriasoft.archidata.dataAccess.options.Condition;
|
||||||
|
import org.atriasoft.karideo.model.Season;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.DELETE;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.PUT;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
@Path("/season")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public class SeasonResource {
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(SeasonResource.class);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Operation(description = "Get a specific Season with his ID", tags = "GLOBAL")
|
||||||
|
public List<Season> gets() throws Exception {
|
||||||
|
return DataAccess.gets(Season.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(description = "Get all season", tags = "GLOBAL")
|
||||||
|
public Season get(@PathParam("oid") final ObjectId oid) throws Exception {
|
||||||
|
return DataAccess.get(Season.class, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================================= ADMIN SECTION: ============================================================================= */
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(description = "Create a new season", tags = "GLOBAL")
|
||||||
|
public Season post(@Valid @ValidGroup(GroupCreate.class) final Season season) throws Exception {
|
||||||
|
return DataAccess.insert(season);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(description = "Modify a specific season", tags = "GLOBAL")
|
||||||
|
public Season put(@PathParam("oid") final ObjectId oid, @Valid @ValidGroup(GroupUpdate.class) final Season season) throws Exception {
|
||||||
|
season.oid = oid;
|
||||||
|
DataAccess.update(season, oid);
|
||||||
|
return DataAccess.get(Season.class, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Operation(description = "Remove a specific season", tags = "GLOBAL")
|
||||||
|
public void remove(@PathParam("oid") final ObjectId oid) throws Exception {
|
||||||
|
DataAccess.delete(Season.class, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Season getOrCreate(final String name, final ObjectId seriesId) {
|
||||||
|
try {
|
||||||
|
Season out = DataAccess.getWhere(Season.class, new Condition(new QueryAnd(new QueryCondition("name", "=", name), new QueryCondition("seriesId", "=", seriesId))));
|
||||||
|
if (out == null) {
|
||||||
|
out = new Season();
|
||||||
|
out.name = name;
|
||||||
|
out.seriesId = seriesId;
|
||||||
|
out = DataAccess.insert(out);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
100
back/src/org/atriasoft/karideo/api/SeriesResource.java
Normal file
100
back/src/org/atriasoft/karideo/api/SeriesResource.java
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
package org.atriasoft.karideo.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.checker.GroupCreate;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.GroupUpdate;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.ValidGroup;
|
||||||
|
import org.atriasoft.archidata.dataAccess.DataAccess;
|
||||||
|
import org.atriasoft.archidata.dataAccess.QueryAnd;
|
||||||
|
import org.atriasoft.archidata.dataAccess.QueryCondition;
|
||||||
|
import org.atriasoft.archidata.dataAccess.options.Condition;
|
||||||
|
import org.atriasoft.karideo.model.Series;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.DELETE;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.PUT;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
@Path("/series")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public class SeriesResource {
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(SeriesResource.class);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Operation(description = "Get all Series", tags = "GLOBAL")
|
||||||
|
public List<Series> gets() throws Exception {
|
||||||
|
return DataAccess.gets(Series.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(description = "Get a specific Series with his ID", tags = "GLOBAL")
|
||||||
|
public Series get(@PathParam("oid") final ObjectId oid) throws Exception {
|
||||||
|
return DataAccess.get(Series.class, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Series getId(final ObjectId oid) throws Exception {
|
||||||
|
return DataAccess.get(Series.class, oid);
|
||||||
|
}
|
||||||
|
/* ============================================================================= ADMIN SECTION: ============================================================================= */
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(description = "Create a new Series", tags = "GLOBAL")
|
||||||
|
public Series post(@Valid @ValidGroup(GroupCreate.class) final Series jsonRequest) throws Exception {
|
||||||
|
return DataAccess.insert(jsonRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(description = "Modify a specific Series", tags = "GLOBAL")
|
||||||
|
public Series put(@PathParam("oid") final ObjectId oid, @Valid @ValidGroup(GroupUpdate.class) final Series series) throws Exception {
|
||||||
|
series.oid = oid;
|
||||||
|
DataAccess.update(series, oid);
|
||||||
|
return DataAccess.get(Series.class, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Operation(description = "Remove a specific Series", tags = "GLOBAL")
|
||||||
|
public void remove(@PathParam("oid") final ObjectId oid) throws Exception {
|
||||||
|
DataAccess.delete(Series.class, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Series getOrCreate(final String name, final ObjectId typeId) {
|
||||||
|
try {
|
||||||
|
Series out = DataAccess.getWhere(Series.class, new Condition(new QueryAnd(new QueryCondition("name", "=", name), new QueryCondition("typeId", "=", typeId))));
|
||||||
|
if (out == null) {
|
||||||
|
out = new Series();
|
||||||
|
out.name = name;
|
||||||
|
out.typeId = typeId;
|
||||||
|
out = DataAccess.insert(out);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
99
back/src/org/atriasoft/karideo/api/TypeResource.java
Normal file
99
back/src/org/atriasoft/karideo/api/TypeResource.java
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
package org.atriasoft.karideo.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.checker.GroupCreate;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.GroupUpdate;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.ValidGroup;
|
||||||
|
import org.atriasoft.archidata.dataAccess.DataAccess;
|
||||||
|
import org.atriasoft.archidata.dataAccess.QueryCondition;
|
||||||
|
import org.atriasoft.archidata.dataAccess.options.Condition;
|
||||||
|
import org.atriasoft.karideo.model.Type;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.DELETE;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.PUT;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
@Path("/type")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public class TypeResource {
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(TypeResource.class);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Operation(description = "Get all Type", tags = "GLOBAL")
|
||||||
|
public List<Type> gets() throws Exception {
|
||||||
|
return DataAccess.gets(Type.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(description = "Get a specific Type with his ID", tags = "GLOBAL")
|
||||||
|
public Type get(@PathParam("oid") final ObjectId oid) throws Exception {
|
||||||
|
return DataAccess.get(Type.class, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getId(final ObjectId oid) throws Exception {
|
||||||
|
return DataAccess.get(Type.class, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================================= ADMIN SECTION: ============================================================================= */
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(description = "Create a new Type", tags = "GLOBAL")
|
||||||
|
public Type post(@Valid @ValidGroup(GroupCreate.class) final Type jsonRequest) throws Exception {
|
||||||
|
return DataAccess.insert(jsonRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(description = "Modify a specific Type", tags = "GLOBAL")
|
||||||
|
public Type patch(@PathParam("oid") final ObjectId oid, @Valid @ValidGroup(GroupUpdate.class) final Type type) throws Exception {
|
||||||
|
type.oid = oid;
|
||||||
|
DataAccess.update(type, oid);
|
||||||
|
return DataAccess.get(Type.class, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("ADMIN")
|
||||||
|
@Operation(description = "Remove a specific Type", tags = "GLOBAL")
|
||||||
|
public void remove(@PathParam("oid") final ObjectId oid) throws Exception {
|
||||||
|
DataAccess.delete(Type.class, oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getOrCreate(final String name) {
|
||||||
|
try {
|
||||||
|
Type out = DataAccess.getWhere(Type.class, new Condition(new QueryCondition("name", "=", name)));
|
||||||
|
if (out == null) {
|
||||||
|
out = new Type();
|
||||||
|
out.name = name;
|
||||||
|
out = DataAccess.insert(out);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package org.atriasoft.karideo.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.checker.GroupUpdate;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.ValidGroup;
|
||||||
|
import org.atriasoft.archidata.dataAccess.DataAccess;
|
||||||
|
import org.atriasoft.archidata.dataAccess.QueryAnd;
|
||||||
|
import org.atriasoft.archidata.dataAccess.QueryCondition;
|
||||||
|
import org.atriasoft.archidata.dataAccess.options.Condition;
|
||||||
|
import org.atriasoft.archidata.dataAccess.options.FilterValue;
|
||||||
|
import org.atriasoft.archidata.filter.GenericContext;
|
||||||
|
import org.atriasoft.karideo.model.UserMediaAdvancement;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.DELETE;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.PUT;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.core.Context;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import jakarta.ws.rs.core.SecurityContext;
|
||||||
|
|
||||||
|
@Path("/advancement")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public class UserMediaAdvancementResource {
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(UserMediaAdvancementResource.class);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Operation(description = "Get a specific user advancement with his ID", tags = "GLOBAL")
|
||||||
|
public UserMediaAdvancement get(@Context final SecurityContext sc, @PathParam("oid") final ObjectId oid) throws Exception {
|
||||||
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
return DataAccess.getWhere(UserMediaAdvancement.class, new Condition(new QueryAnd(new QueryCondition("mediaId", "=", oid), new QueryCondition("userId", "=", gc.userByToken.oid))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Operation(description = "Get all user advancement", tags = "GLOBAL")
|
||||||
|
public List<UserMediaAdvancement> gets(@Context final SecurityContext sc) throws Exception {
|
||||||
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
return DataAccess.getsWhere(UserMediaAdvancement.class, new Condition(new QueryCondition("userId", "=", gc.userByToken.oid)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================================= Modification SECTION: ============================================================================= */
|
||||||
|
|
||||||
|
public record MediaInformations(int time, float percent, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// @POST
|
||||||
|
// @Path("{id}")
|
||||||
|
// @RolesAllowed("USER")
|
||||||
|
// @Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public UserMediaAdvancement post(@Context final SecurityContext sc, @PathParam("oid") final ObjectId oid, final MediaInformations data) throws Exception {
|
||||||
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
final UserMediaAdvancement elem = new UserMediaAdvancement();
|
||||||
|
elem.userId = gc.userByToken.oid;
|
||||||
|
elem.mediaId = oid;
|
||||||
|
elem.time = data.time;
|
||||||
|
elem.percent = data.percent;
|
||||||
|
elem.count = data.count;
|
||||||
|
return DataAccess.insert(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public record MediaInformationsDelta(int time, float percent, boolean addCount) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(description = "Modify a user advancement", tags = "GLOBAL")
|
||||||
|
public UserMediaAdvancement put(@Context final SecurityContext sc, @PathParam("oid") final ObjectId oid, @Valid @ValidGroup(GroupUpdate.class) final MediaInformationsDelta data) throws Exception {
|
||||||
|
final UserMediaAdvancement elem = get(sc, oid);
|
||||||
|
if (elem == null) {
|
||||||
|
// insert element
|
||||||
|
if (data.addCount) {
|
||||||
|
return post(sc, oid, new MediaInformations(data.time(), data.percent(), 1));
|
||||||
|
} else {
|
||||||
|
return post(sc, oid, new MediaInformations(data.time(), data.percent(), 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elem.time = data.time;
|
||||||
|
elem.percent = data.percent;
|
||||||
|
if (data.addCount) {
|
||||||
|
elem.count++;
|
||||||
|
}
|
||||||
|
LOGGER.info("{},{},{}", elem.time, elem.percent, elem.count);
|
||||||
|
DataAccess.update(elem, elem.oid, new FilterValue("time", "percent", "count"));
|
||||||
|
return DataAccess.get(UserMediaAdvancement.class, elem.oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{oid}")
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Operation(description = "Remove a specific user advancement", tags = "GLOBAL")
|
||||||
|
public void remove(@Context final SecurityContext sc, @PathParam("oid") final ObjectId oid) throws Exception {
|
||||||
|
final UserMediaAdvancement elem = get(sc, oid);
|
||||||
|
DataAccess.delete(UserMediaAdvancement.class, elem.oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
package org.kar.karideo.api;
|
package org.atriasoft.karideo.api;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
import org.atriasoft.archidata.dataAccess.DataAccess;
|
||||||
import org.kar.archidata.filter.GenericContext;
|
import org.atriasoft.archidata.filter.GenericContext;
|
||||||
import org.kar.karideo.model.UserKarideo;
|
import org.atriasoft.karideo.model.UserKarideo;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
@@ -20,17 +22,17 @@ import jakarta.ws.rs.core.MediaType;
|
|||||||
import jakarta.ws.rs.core.SecurityContext;
|
import jakarta.ws.rs.core.SecurityContext;
|
||||||
|
|
||||||
@Path("/users")
|
@Path("/users")
|
||||||
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public class UserResource {
|
public class UserResource {
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(UserResource.class);
|
static final Logger LOGGER = LoggerFactory.getLogger(UserResource.class);
|
||||||
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
public class UserOut {
|
public class UserOut {
|
||||||
public long id;
|
public ObjectId oid;
|
||||||
public String login;
|
public String login;
|
||||||
|
|
||||||
public UserOut(final long id, final String login) {
|
public UserOut(final ObjectId oid, final String login) {
|
||||||
this.id = id;
|
this.oid = oid;
|
||||||
this.login = login;
|
this.login = login;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +43,8 @@ public class UserResource {
|
|||||||
// curl http://localhost:9993/api/users
|
// curl http://localhost:9993/api/users
|
||||||
@GET
|
@GET
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
public List<UserKarideo> getUsers() {
|
@Operation(description = "Get all the users", tags = "SYSTEM")
|
||||||
|
public List<UserKarideo> gets() {
|
||||||
System.out.println("getUsers");
|
System.out.println("getUsers");
|
||||||
try {
|
try {
|
||||||
return DataAccess.gets(UserKarideo.class);
|
return DataAccess.gets(UserKarideo.class);
|
||||||
@@ -54,9 +57,10 @@ public class UserResource {
|
|||||||
|
|
||||||
// curl http://localhost:9993/api/users/3
|
// curl http://localhost:9993/api/users/3
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}")
|
@Path("{oid}")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
public UserKarideo getUsers(@Context final SecurityContext sc, @PathParam("id") final long userId) {
|
@Operation(description = "Get a specific user data", tags = "SYSTEM")
|
||||||
|
public UserKarideo get(@Context final SecurityContext sc, @PathParam("oid") final ObjectId userId) {
|
||||||
System.out.println("getUser " + userId);
|
System.out.println("getUser " + userId);
|
||||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
System.out.println("===================================================");
|
System.out.println("===================================================");
|
||||||
@@ -74,11 +78,12 @@ public class UserResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("me")
|
@Path("me")
|
||||||
@RolesAllowed("USER")
|
@RolesAllowed("USER")
|
||||||
|
@Operation(description = "Get the user personal data", tags = "SYSTEM")
|
||||||
public UserOut getMe(@Context final SecurityContext sc) {
|
public UserOut getMe(@Context final SecurityContext sc) {
|
||||||
LOGGER.debug("getMe()");
|
LOGGER.debug("getMe()");
|
||||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
LOGGER.debug("== USER ? {}", gc.userByToken);
|
LOGGER.debug("== USER ? {}", gc.userByToken);
|
||||||
return new UserOut(gc.userByToken.id, gc.userByToken.name);
|
return new UserOut(gc.userByToken.oid, gc.userByToken.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.kar.karideo.filter;
|
package org.atriasoft.karideo.filter;
|
||||||
|
|
||||||
import org.kar.archidata.filter.AuthenticationFilter;
|
import org.atriasoft.archidata.filter.AuthenticationFilter;
|
||||||
|
|
||||||
import jakarta.ws.rs.Priorities;
|
import jakarta.ws.rs.Priorities;
|
||||||
import jakarta.ws.rs.ext.Provider;
|
import jakarta.ws.rs.ext.Provider;
|
||||||
60
back/src/org/atriasoft/karideo/internal/Log.java
Normal file
60
back/src/org/atriasoft/karideo/internal/Log.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package org.atriasoft.karideo.internal;
|
||||||
|
|
||||||
|
//import io.scenarium.logger.LogLevel;
|
||||||
|
//import io.scenarium.logger.Logger;
|
||||||
|
|
||||||
|
public class Log {
|
||||||
|
// private static final String LIB_NAME = "logger";
|
||||||
|
// private static final String LIB_NAME_DRAW = Logger.getDrawableName(LIB_NAME);
|
||||||
|
// private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(LIB_NAME, LogLevel.CRITICAL);
|
||||||
|
// private static final boolean PRINT_ERROR = Logger.getNeedPrint(LIB_NAME, LogLevel.ERROR);
|
||||||
|
// private static final boolean PRINT_WARNING = Logger.getNeedPrint(LIB_NAME, LogLevel.WARNING);
|
||||||
|
// private static final boolean PRINT_INFO = Logger.getNeedPrint(LIB_NAME, LogLevel.INFO);
|
||||||
|
// private static final boolean PRINT_DEBUG = Logger.getNeedPrint(LIB_NAME, LogLevel.DEBUG);
|
||||||
|
// private static final boolean PRINT_VERBOSE = Logger.getNeedPrint(LIB_NAME, LogLevel.VERBOSE);
|
||||||
|
// private static final boolean PRINT_TODO = Logger.getNeedPrint(LIB_NAME, LogLevel.TODO);
|
||||||
|
// private static final boolean PRINT_PRINT = Logger.getNeedPrint(LIB_NAME, LogLevel.PRINT);
|
||||||
|
//
|
||||||
|
// private Log() {}
|
||||||
|
//
|
||||||
|
// public static void print(String data) {
|
||||||
|
// if (PRINT_PRINT)
|
||||||
|
// Logger.print(LIB_NAME_DRAW, data);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static void todo(String data) {
|
||||||
|
// if (PRINT_TODO)
|
||||||
|
// Logger.todo(LIB_NAME_DRAW, data);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static void critical(String data) {
|
||||||
|
// if (PRINT_CRITICAL)
|
||||||
|
// Logger.critical(LIB_NAME_DRAW, data);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static void error(String data) {
|
||||||
|
// if (PRINT_ERROR)
|
||||||
|
// Logger.error(LIB_NAME_DRAW, data);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static void warning(String data) {
|
||||||
|
// if (PRINT_WARNING)
|
||||||
|
// Logger.warning(LIB_NAME_DRAW, data);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static void info(String data) {
|
||||||
|
// if (PRINT_INFO)
|
||||||
|
// Logger.info(LIB_NAME_DRAW, data);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static void debug(String data) {
|
||||||
|
// if (PRINT_DEBUG)
|
||||||
|
// Logger.debug(LIB_NAME_DRAW, data);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static void verbose(String data) {
|
||||||
|
// if (PRINT_VERBOSE)
|
||||||
|
// Logger.verbose(LIB_NAME_DRAW, data);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
47
back/src/org/atriasoft/karideo/job/BackupJob.java
Normal file
47
back/src/org/atriasoft/karideo/job/BackupJob.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package org.atriasoft.karideo.job;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.backup.BackupEngine;
|
||||||
|
import org.atriasoft.archidata.backup.BackupEngine.EngineBackupType;
|
||||||
|
import org.atriasoft.archidata.exception.DataAccessException;
|
||||||
|
import org.atriasoft.archidata.tools.ConfigBaseVariable;
|
||||||
|
import org.atriasoft.karideo.migration.Initialization;
|
||||||
|
import org.atriasoft.karideo.util.ConfigVariable;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class BackupJob implements Runnable {
|
||||||
|
|
||||||
|
final static Logger LOGGER = LoggerFactory.getLogger(BackupJob.class);
|
||||||
|
BackupEngine engine;
|
||||||
|
|
||||||
|
public BackupJob() throws DataAccessException, IOException {
|
||||||
|
final Path path = Paths.get(ConfigVariable.getBackupFolder());
|
||||||
|
Files.createDirectories(path);
|
||||||
|
this.engine = new BackupEngine(path, ConfigBaseVariable.getDBName(), EngineBackupType.JSON_EXTENDED);
|
||||||
|
this.engine.setEnableStoreOrRestoreData(false);
|
||||||
|
for (final Class<?> clazz : Initialization.CLASSES_BASE) {
|
||||||
|
this.engine.addClass(clazz);
|
||||||
|
}
|
||||||
|
this.engine.addCollection("counters");
|
||||||
|
this.engine.addCollection("KAR_migration");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
LOGGER.warn("Backup request");
|
||||||
|
try {
|
||||||
|
final String timestampUtc = ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH:mm:ss.SSS"));
|
||||||
|
this.engine.store(timestampUtc + "_full");
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
LOGGER.error("Fail in Backup: {}", ex.getMessage());
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
131
back/src/org/atriasoft/karideo/migration/Initialization.java
Normal file
131
back/src/org/atriasoft/karideo/migration/Initialization.java
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
package org.atriasoft.karideo.migration;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.api.DataResource;
|
||||||
|
import org.atriasoft.archidata.backup.BackupEngine;
|
||||||
|
import org.atriasoft.archidata.backup.BackupEngine.EngineBackupType;
|
||||||
|
import org.atriasoft.archidata.dataAccess.DBAccess;
|
||||||
|
import org.atriasoft.archidata.db.DbConfig;
|
||||||
|
import org.atriasoft.archidata.exception.DataAccessException;
|
||||||
|
import org.atriasoft.archidata.exception.FailException;
|
||||||
|
import org.atriasoft.archidata.externalRestApi.AnalyzeApi;
|
||||||
|
import org.atriasoft.archidata.externalRestApi.TsGenerateApi;
|
||||||
|
import org.atriasoft.archidata.filter.PartRight;
|
||||||
|
import org.atriasoft.archidata.migration.MigrationSqlStep;
|
||||||
|
import org.atriasoft.archidata.model.Data;
|
||||||
|
import org.atriasoft.archidata.model.User;
|
||||||
|
import org.atriasoft.archidata.model.token.JwtToken;
|
||||||
|
import org.atriasoft.archidata.tools.ConfigBaseVariable;
|
||||||
|
import org.atriasoft.karideo.api.Front;
|
||||||
|
import org.atriasoft.karideo.api.HealthCheck;
|
||||||
|
import org.atriasoft.karideo.api.MediaResource;
|
||||||
|
import org.atriasoft.karideo.api.SeasonResource;
|
||||||
|
import org.atriasoft.karideo.api.SeriesResource;
|
||||||
|
import org.atriasoft.karideo.api.TypeResource;
|
||||||
|
import org.atriasoft.karideo.api.UserMediaAdvancementResource;
|
||||||
|
import org.atriasoft.karideo.api.UserResource;
|
||||||
|
import org.atriasoft.karideo.model.Media;
|
||||||
|
import org.atriasoft.karideo.model.Season;
|
||||||
|
import org.atriasoft.karideo.model.Series;
|
||||||
|
import org.atriasoft.karideo.model.Type;
|
||||||
|
import org.atriasoft.karideo.model.UserMediaAdvancement;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.InternalServerErrorException;
|
||||||
|
|
||||||
|
public class Initialization extends MigrationSqlStep {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(Initialization.class);
|
||||||
|
|
||||||
|
public static final int KARSO_INITIALISATION_ID = 1;
|
||||||
|
|
||||||
|
public static final List<Class<?>> CLASSES_BASE = List.of(Data.class, Media.class, Type.class, Series.class, Season.class, User.class, UserMediaAdvancement.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Initialization";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeDB() throws DataAccessException, InternalServerErrorException, IOException {
|
||||||
|
final DbConfig config = new DbConfig();
|
||||||
|
LOGGER.info("Remove DB '{}'", config.getDbName());
|
||||||
|
try (DBAccess dba = DBAccess.createInterface(config)) {
|
||||||
|
dba.deleteDB(ConfigBaseVariable.bdDatabase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Restore backup file (./init/backup.tar.gz). */
|
||||||
|
public static void initializeWithBackup() throws IOException, DataAccessException, FailException {
|
||||||
|
final Path path = Paths.get("./init/backup.tar.gz");
|
||||||
|
if (!Files.exists(path)) {
|
||||||
|
throw new FailException("file: ./init/backup.tar.gz does not exist");
|
||||||
|
}
|
||||||
|
removeDB();
|
||||||
|
final BackupEngine engine = new BackupEngine(Paths.get("."), ConfigBaseVariable.bdDatabase, EngineBackupType.JSON_EXTENDED);
|
||||||
|
if (!engine.restoreFile(path, null)) {
|
||||||
|
throw new FailException("Can not retrieve db from backup");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void generateObjects() throws Exception {
|
||||||
|
LOGGER.info("Generate APIs");
|
||||||
|
final List<Class<?>> listOfResources = List.of(Front.class, HealthCheck.class, SeasonResource.class, SeriesResource.class, TypeResource.class, UserMediaAdvancementResource.class,
|
||||||
|
UserResource.class, MediaResource.class, DataResource.class);
|
||||||
|
final AnalyzeApi api = new AnalyzeApi();
|
||||||
|
api.addAllApi(listOfResources);
|
||||||
|
api.addModel(JwtToken.class);
|
||||||
|
api.addModel(PartRight.class);
|
||||||
|
TsGenerateApi.generateApi(api, Paths.get("../front/src/back-api/"));
|
||||||
|
LOGGER.info("Generate APIs (DONE)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateStep() throws Exception {
|
||||||
|
for (final Class<?> clazz : CLASSES_BASE) {
|
||||||
|
addClass(clazz);
|
||||||
|
}
|
||||||
|
addAction((final DBAccess da) -> {
|
||||||
|
final List<Type> data = List.of(//
|
||||||
|
new Type("Documentary", "Documentary (animals, space, earth...)"), //
|
||||||
|
new Type("Movie", "Movie with real humans (film)"), //
|
||||||
|
new Type("Animation", "Animation movies (film)"), //
|
||||||
|
new Type("Short movie", "Small movies (less 2 minutes)"), //
|
||||||
|
new Type("TV show", "TV show for old peoples"), //
|
||||||
|
new Type("Animation TV show", "TV show for young peoples"), //
|
||||||
|
new Type("Theater", "Theater play"), //
|
||||||
|
new Type("One man show", "Recorded stand up"), //
|
||||||
|
new Type("Concert", "Recorded concert"), //
|
||||||
|
new Type("Opera", "Recorded opera") //
|
||||||
|
);
|
||||||
|
da.insertMultiple(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void dropAll(final DBAccess da) {
|
||||||
|
for (final Class<?> element : CLASSES_BASE) {
|
||||||
|
try {
|
||||||
|
da.drop(element);
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
LOGGER.error("Fail to drop table !!!!!!");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cleanAll(final DBAccess da) {
|
||||||
|
for (final Class<?> element : CLASSES_BASE) {
|
||||||
|
try {
|
||||||
|
da.cleanAll(element);
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
LOGGER.error("Fail to clean table !!!!!!");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.atriasoft.karideo.migration;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.dataAccess.DBAccess;
|
||||||
|
import org.atriasoft.archidata.migration.MigrationSqlStep;
|
||||||
|
import org.atriasoft.karideo.migration.model.TypeOld;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class Migration20250928 extends MigrationSqlStep {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(Migration20250928.class);
|
||||||
|
|
||||||
|
public static final int KARSO_INITIALISATION_ID = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "migration-2025-10-12: Fix UserId in advencement";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ObjectId getElementType(final List<TypeOld> datas, final Long id) throws Exception {
|
||||||
|
if (id == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (final var elem : datas) {
|
||||||
|
if (elem.id.equals(id)) {
|
||||||
|
return elem.getOid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Exception("Does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateStep() throws Exception {
|
||||||
|
addAction((final DBAccess daMongo) -> {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
85
back/src/org/atriasoft/karideo/migration/model/MediaOld.java
Normal file
85
back/src/org/atriasoft/karideo/migration/model/MediaOld.java
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
package org.atriasoft.karideo.migration.model;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.DataJson;
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CheckForeignKey;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CollectionNotEmpty;
|
||||||
|
import org.atriasoft.archidata.model.Data;
|
||||||
|
import org.atriasoft.archidata.model.GenericDataSoftDelete;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.hibernate.validator.constraints.UniqueElements;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.annotation.Nullable;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.validation.constraints.PositiveOrZero;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "media")
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
|
public class MediaOld extends GenericDataSoftDelete {
|
||||||
|
@Schema(description = "Name of the media (this represent the title)")
|
||||||
|
@Column(nullable = false, length = 0)
|
||||||
|
@Size(min = 0, max = 256)
|
||||||
|
public String name;
|
||||||
|
@Schema(description = "Description of the media")
|
||||||
|
@Column(length = 0)
|
||||||
|
@Size(min = 0, max = 8192)
|
||||||
|
public String description;
|
||||||
|
@Schema(description = "Foreign Key Id of the data")
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Data.class)
|
||||||
|
@Column(nullable = false)
|
||||||
|
@CheckForeignKey(target = Data.class)
|
||||||
|
public ObjectId dataId;
|
||||||
|
@Schema(description = "Type of the media")
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, targetEntity = TypeOld.class)
|
||||||
|
@CheckForeignKey(target = TypeOld.class)
|
||||||
|
public Long typeId;
|
||||||
|
@Schema(description = "Series reference of the media")
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, targetEntity = SeriesOld.class)
|
||||||
|
@CheckForeignKey(target = SeriesOld.class)
|
||||||
|
public Long seriesId;
|
||||||
|
@Schema(description = "Season reference of the media")
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, targetEntity = SeasonOld.class)
|
||||||
|
@CheckForeignKey(target = SeasonOld.class)
|
||||||
|
public Long seasonId;
|
||||||
|
@Schema(description = "Episode Id")
|
||||||
|
@PositiveOrZero
|
||||||
|
public Integer episode;
|
||||||
|
@Schema(description = "Creation years of the media")
|
||||||
|
public Date datePublication;
|
||||||
|
@Schema(description = "Limitation Age of the media")
|
||||||
|
@PositiveOrZero
|
||||||
|
public Integer ageLimit;
|
||||||
|
@Schema(description = "List of Id of the specific covers")
|
||||||
|
@DataJson()
|
||||||
|
@Nullable
|
||||||
|
@CollectionNotEmpty
|
||||||
|
@UniqueElements
|
||||||
|
public List<@CheckForeignKey(target = Data.class) ObjectId> covers = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Media [name=" + this.name + ", description=" + this.description + ", dataId=" + this.dataId + ", typeId=" + this.typeId + ", seriesId=" + this.seriesId + ", seasonId=" + this.seasonId
|
||||||
|
+ ", episode=" + this.episode + ", date=" + this.datePublication + ", ageLimit=" + this.ageLimit + ", covers=" + this.covers + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Column(nullable = true)
|
||||||
|
private final ObjectId oid = new ObjectId();
|
||||||
|
|
||||||
|
public ObjectId getOid() {
|
||||||
|
return this.oid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package org.atriasoft.karideo.migration.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.DataIfNotExists;
|
||||||
|
import org.atriasoft.archidata.annotation.DataJson;
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CheckForeignKey;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CollectionNotEmpty;
|
||||||
|
import org.atriasoft.archidata.model.Data;
|
||||||
|
import org.atriasoft.archidata.model.GenericDataSoftDelete;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.hibernate.validator.constraints.UniqueElements;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.annotation.Nullable;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
|
@Table(name = "season")
|
||||||
|
@DataIfNotExists
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
|
public class SeasonOld extends GenericDataSoftDelete {
|
||||||
|
@Column(nullable = false, length = 0)
|
||||||
|
@Schema(description = "Name of the media (this represent the title)")
|
||||||
|
@Size(min = 0, max = 256)
|
||||||
|
public String name;
|
||||||
|
@Column(length = 0)
|
||||||
|
@Schema(description = "Description of the media")
|
||||||
|
@Size(min = 0, max = 8192)
|
||||||
|
public String description;
|
||||||
|
@Column(nullable = false)
|
||||||
|
@Schema(description = "series parent ID")
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, targetEntity = SeriesOld.class)
|
||||||
|
@CheckForeignKey(target = SeriesOld.class)
|
||||||
|
public Long parentId;
|
||||||
|
@Schema(description = "List of Id of the specific covers")
|
||||||
|
@DataJson()
|
||||||
|
@Nullable
|
||||||
|
@CollectionNotEmpty
|
||||||
|
@UniqueElements
|
||||||
|
public List<@CheckForeignKey(target = Data.class) @NotNull ObjectId> covers = null;
|
||||||
|
|
||||||
|
@Column(nullable = true)
|
||||||
|
private final ObjectId oid = new ObjectId();
|
||||||
|
|
||||||
|
public ObjectId getOid() {
|
||||||
|
return this.oid;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package org.atriasoft.karideo.migration.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.DataIfNotExists;
|
||||||
|
import org.atriasoft.archidata.annotation.DataJson;
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CheckForeignKey;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CollectionNotEmpty;
|
||||||
|
import org.atriasoft.archidata.model.Data;
|
||||||
|
import org.atriasoft.archidata.model.GenericDataSoftDelete;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.hibernate.validator.constraints.UniqueElements;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.annotation.Nullable;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
|
@Table(name = "series")
|
||||||
|
@DataIfNotExists
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
|
public class SeriesOld extends GenericDataSoftDelete {
|
||||||
|
@Column(nullable = false, length = 0)
|
||||||
|
@Size(min = 0, max = 256)
|
||||||
|
@Schema(description = "Name of the media (this represent the title)")
|
||||||
|
public String name;
|
||||||
|
@Column(length = 0)
|
||||||
|
@Schema(description = "Description of the media")
|
||||||
|
@Size(min = 0, max = 8192)
|
||||||
|
public String description;
|
||||||
|
@Column(nullable = false)
|
||||||
|
@Schema(description = "series parent ID")
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, targetEntity = TypeOld.class)
|
||||||
|
@CheckForeignKey(target = TypeOld.class)
|
||||||
|
public Long parentId;
|
||||||
|
@Schema(description = "List of Id of the specific covers")
|
||||||
|
@DataJson()
|
||||||
|
@Nullable
|
||||||
|
@CollectionNotEmpty
|
||||||
|
@UniqueElements
|
||||||
|
public List<@CheckForeignKey(target = Data.class) @NotNull ObjectId> covers = null;
|
||||||
|
@Column(nullable = true)
|
||||||
|
private final ObjectId oid = new ObjectId();
|
||||||
|
|
||||||
|
public ObjectId getOid() {
|
||||||
|
return this.oid;
|
||||||
|
}
|
||||||
|
}
|
||||||
58
back/src/org/atriasoft/karideo/migration/model/TypeOld.java
Normal file
58
back/src/org/atriasoft/karideo/migration/model/TypeOld.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package org.atriasoft.karideo.migration.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.DataIfNotExists;
|
||||||
|
import org.atriasoft.archidata.annotation.DataJson;
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CheckForeignKey;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CollectionNotEmpty;
|
||||||
|
import org.atriasoft.archidata.model.Data;
|
||||||
|
import org.atriasoft.archidata.model.GenericDataSoftDelete;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.hibernate.validator.constraints.UniqueElements;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.annotation.Nullable;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
|
@Table(name = "type")
|
||||||
|
@DataIfNotExists
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
|
public class TypeOld extends GenericDataSoftDelete {
|
||||||
|
@Column(nullable = false, length = 0)
|
||||||
|
@Size(min = 0, max = 256)
|
||||||
|
@Schema(description = "Name of the media (this represent the title)")
|
||||||
|
public String name;
|
||||||
|
@Column(length = 0)
|
||||||
|
@Schema(description = "Description of the media")
|
||||||
|
@Size(min = 0, max = 8192)
|
||||||
|
public String description;
|
||||||
|
@Schema(description = "List of Id of the specific covers")
|
||||||
|
@DataJson()
|
||||||
|
@Nullable
|
||||||
|
@CollectionNotEmpty
|
||||||
|
@UniqueElements
|
||||||
|
public List<@CheckForeignKey(target = Data.class) @NotNull ObjectId> covers = null;
|
||||||
|
|
||||||
|
public TypeOld() {}
|
||||||
|
|
||||||
|
public TypeOld(final String name, final String description) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Column(nullable = true)
|
||||||
|
private final ObjectId oid = new ObjectId();
|
||||||
|
|
||||||
|
public ObjectId getOid() {
|
||||||
|
return this.oid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package org.atriasoft.karideo.migration.model;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.DataIfNotExists;
|
||||||
|
import org.atriasoft.archidata.annotation.DataNotRead;
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiAccessLimitation;
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CheckForeignKey;
|
||||||
|
import org.atriasoft.archidata.model.GenericDataSoftDelete;
|
||||||
|
import org.atriasoft.karideo.model.UserKarideo;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.annotation.Nullable;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.validation.constraints.PositiveOrZero;
|
||||||
|
|
||||||
|
@Table(name = "userMediaAdvancement")
|
||||||
|
@DataIfNotExists
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
|
public class UserMediaAdvancementOld extends GenericDataSoftDelete {
|
||||||
|
@DataNotRead
|
||||||
|
@Column(nullable = false)
|
||||||
|
@Schema(description = "Foreign Key Id of the user")
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, targetEntity = UserKarideo.class)
|
||||||
|
@Nullable
|
||||||
|
@ApiAccessLimitation(updatable = false, creatable = false)
|
||||||
|
public Long userId;
|
||||||
|
@Column(nullable = false)
|
||||||
|
@Schema(description = "Id of the media")
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, targetEntity = MediaOld.class)
|
||||||
|
@CheckForeignKey(target = MediaOld.class)
|
||||||
|
public Long mediaId;
|
||||||
|
@Column(nullable = false)
|
||||||
|
@Schema(description = "Percent of advancement in the media")
|
||||||
|
@PositiveOrZero
|
||||||
|
public Float percent;
|
||||||
|
@Column(nullable = false)
|
||||||
|
@Schema(description = "Number of second of advancement in the media")
|
||||||
|
@PositiveOrZero
|
||||||
|
public Integer time;
|
||||||
|
@Column(nullable = false)
|
||||||
|
@Schema(description = "Number of time this media has been read")
|
||||||
|
@PositiveOrZero
|
||||||
|
public Integer count;
|
||||||
|
@Column(nullable = true)
|
||||||
|
private final ObjectId oid = new ObjectId();
|
||||||
|
|
||||||
|
public ObjectId getOid() {
|
||||||
|
return this.oid;
|
||||||
|
}
|
||||||
|
}
|
||||||
68
back/src/org/atriasoft/karideo/model/Media.java
Normal file
68
back/src/org/atriasoft/karideo/model/Media.java
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package org.atriasoft.karideo.model;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CheckForeignKey;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CollectionNotEmpty;
|
||||||
|
import org.atriasoft.archidata.model.Data;
|
||||||
|
import org.atriasoft.archidata.model.OIDGenericDataSoftDelete;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.hibernate.validator.constraints.UniqueElements;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.annotation.Nullable;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.PositiveOrZero;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
|
public class Media extends OIDGenericDataSoftDelete {
|
||||||
|
@Schema(description = "Name of the media (this represent the title)")
|
||||||
|
@Size(min = 0, max = 256)
|
||||||
|
@NotNull
|
||||||
|
public String name;
|
||||||
|
@Schema(description = "Description of the media")
|
||||||
|
@Size(min = 0, max = 8192)
|
||||||
|
public String description;
|
||||||
|
@Schema(description = "Foreign Key Id of the data")
|
||||||
|
@Column(nullable = false)
|
||||||
|
@CheckForeignKey(target = Data.class)
|
||||||
|
public ObjectId dataId;
|
||||||
|
@Schema(description = "Type of the media")
|
||||||
|
@CheckForeignKey(target = Type.class)
|
||||||
|
public ObjectId typeId;
|
||||||
|
@Schema(description = "Series reference of the media")
|
||||||
|
@CheckForeignKey(target = Series.class)
|
||||||
|
public ObjectId seriesId;
|
||||||
|
@Schema(description = "Season reference of the media")
|
||||||
|
@CheckForeignKey(target = Season.class)
|
||||||
|
public ObjectId seasonId;
|
||||||
|
@Schema(description = "Episode Id")
|
||||||
|
@PositiveOrZero
|
||||||
|
public Integer episode;
|
||||||
|
@Schema(description = "Creation years of the media")
|
||||||
|
public Date datePublication;
|
||||||
|
@Schema(description = "Limitation Age of the media")
|
||||||
|
@PositiveOrZero
|
||||||
|
public Integer ageLimit;
|
||||||
|
@Schema(description = "List of Id of the specific covers")
|
||||||
|
@Nullable
|
||||||
|
@CollectionNotEmpty
|
||||||
|
@UniqueElements
|
||||||
|
public List<@CheckForeignKey(target = Data.class) ObjectId> covers = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Media [name=" + this.name + ", description=" + this.description + ", dataId=" + this.dataId + ", typeId=" + this.typeId + ", seriesId=" + this.seriesId + ", seasonId=" + this.seasonId
|
||||||
|
+ ", episode=" + this.episode + ", date=" + this.datePublication + ", ageLimit=" + this.ageLimit + ", covers=" + this.covers + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
42
back/src/org/atriasoft/karideo/model/Season.java
Normal file
42
back/src/org/atriasoft/karideo/model/Season.java
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package org.atriasoft.karideo.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.DataIfNotExists;
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CheckForeignKey;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CollectionNotEmpty;
|
||||||
|
import org.atriasoft.archidata.model.Data;
|
||||||
|
import org.atriasoft.archidata.model.OIDGenericDataSoftDelete;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.hibernate.validator.constraints.UniqueElements;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.annotation.Nullable;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
@DataIfNotExists
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
|
public class Season extends OIDGenericDataSoftDelete {
|
||||||
|
@Schema(description = "Name of the media (this represent the title)")
|
||||||
|
@Size(min = 0, max = 256)
|
||||||
|
public String name;
|
||||||
|
@Schema(description = "Description of the media")
|
||||||
|
@Size(min = 0, max = 8192)
|
||||||
|
public String description;
|
||||||
|
@Schema(description = "series parent ID")
|
||||||
|
// @ManyToOneDoc(targetEntity = Series.class, remoteField = "")
|
||||||
|
@CheckForeignKey(target = Series.class)
|
||||||
|
public ObjectId seriesId;
|
||||||
|
@Schema(description = "List of Id of the specific covers")
|
||||||
|
@Nullable
|
||||||
|
@CollectionNotEmpty
|
||||||
|
@UniqueElements
|
||||||
|
public List<@CheckForeignKey(target = Data.class) @NotNull ObjectId> covers = null;
|
||||||
|
}
|
||||||
45
back/src/org/atriasoft/karideo/model/Series.java
Normal file
45
back/src/org/atriasoft/karideo/model/Series.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package org.atriasoft.karideo.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.DataIfNotExists;
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CheckForeignKey;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CollectionNotEmpty;
|
||||||
|
import org.atriasoft.archidata.model.Data;
|
||||||
|
import org.atriasoft.archidata.model.OIDGenericDataSoftDelete;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.hibernate.validator.constraints.UniqueElements;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.annotation.Nullable;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
@DataIfNotExists
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
|
public class Series extends OIDGenericDataSoftDelete {
|
||||||
|
@Size(min = 0, max = 256)
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "Name of the media (this represent the title)")
|
||||||
|
public String name;
|
||||||
|
@Column(length = 0)
|
||||||
|
@Schema(description = "Description of the media")
|
||||||
|
@Size(min = 0, max = 8192)
|
||||||
|
public String description;
|
||||||
|
@Column(nullable = false)
|
||||||
|
@Schema(description = "series parent ID")
|
||||||
|
@CheckForeignKey(target = Type.class)
|
||||||
|
public ObjectId typeId;
|
||||||
|
@Schema(description = "List of Id of the specific covers")
|
||||||
|
@Nullable
|
||||||
|
@CollectionNotEmpty
|
||||||
|
@UniqueElements
|
||||||
|
public List<@CheckForeignKey(target = Data.class) @NotNull ObjectId> covers = null;
|
||||||
|
}
|
||||||
49
back/src/org/atriasoft/karideo/model/Type.java
Normal file
49
back/src/org/atriasoft/karideo/model/Type.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package org.atriasoft.karideo.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.DataIfNotExists;
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CheckForeignKey;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CollectionNotEmpty;
|
||||||
|
import org.atriasoft.archidata.model.Data;
|
||||||
|
import org.atriasoft.archidata.model.OIDGenericDataSoftDelete;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
import org.hibernate.validator.constraints.UniqueElements;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.annotation.Nullable;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
@DataIfNotExists
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
|
public class Type extends OIDGenericDataSoftDelete {
|
||||||
|
@NotNull
|
||||||
|
@Size(min = 0, max = 256)
|
||||||
|
@Schema(description = "Name of the media (this represent the title)")
|
||||||
|
public String name;
|
||||||
|
@Column(length = 0)
|
||||||
|
@Schema(description = "Description of the media")
|
||||||
|
@Size(min = 0, max = 8192)
|
||||||
|
public String description;
|
||||||
|
@Schema(description = "List of Id of the specific covers")
|
||||||
|
@Nullable
|
||||||
|
@CollectionNotEmpty
|
||||||
|
@UniqueElements
|
||||||
|
public List<@CheckForeignKey(target = Data.class) @NotNull ObjectId> covers = null;
|
||||||
|
|
||||||
|
public Type() {}
|
||||||
|
|
||||||
|
public Type(final String name, final String description) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.kar.karideo.model;
|
package org.atriasoft.karideo.model;
|
||||||
|
|
||||||
import org.kar.archidata.annotation.DataIfNotExists;
|
import org.atriasoft.archidata.annotation.DataIfNotExists;
|
||||||
import org.kar.archidata.model.User;
|
import org.atriasoft.archidata.model.User;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package org.atriasoft.karideo.model;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.annotation.DataIfNotExists;
|
||||||
|
import org.atriasoft.archidata.annotation.DataNotRead;
|
||||||
|
import org.atriasoft.archidata.annotation.apiGenerator.ApiGenerationMode;
|
||||||
|
import org.atriasoft.archidata.annotation.checker.CheckForeignKey;
|
||||||
|
import org.atriasoft.archidata.model.OIDGenericDataSoftDelete;
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.PositiveOrZero;
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
@DataIfNotExists
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@ApiGenerationMode(create = true, update = true)
|
||||||
|
public class UserMediaAdvancement extends OIDGenericDataSoftDelete {
|
||||||
|
@DataNotRead
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "Foreign Key Id of the user")
|
||||||
|
@CheckForeignKey(target = UserKarideo.class)
|
||||||
|
public ObjectId userId;
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "Id of the media")
|
||||||
|
@CheckForeignKey(target = Media.class)
|
||||||
|
public ObjectId mediaId;
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "Percent of advancement in the media")
|
||||||
|
@PositiveOrZero
|
||||||
|
public Float percent;
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "Number of second of advancement in the media")
|
||||||
|
@PositiveOrZero
|
||||||
|
public Integer time;
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "Number of time this media has been read")
|
||||||
|
@PositiveOrZero
|
||||||
|
public Integer count;
|
||||||
|
}
|
||||||
29
back/src/org/atriasoft/karideo/util/ConfigVariable.java
Normal file
29
back/src/org/atriasoft/karideo/util/ConfigVariable.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package org.atriasoft.karideo.util;
|
||||||
|
|
||||||
|
public class ConfigVariable {
|
||||||
|
public static final String BASE_NAME = "ORG_KARIDEO_";
|
||||||
|
|
||||||
|
public static String getFrontFolder() {
|
||||||
|
final String out = System.getenv(BASE_NAME + "FRONT_FOLDER");
|
||||||
|
if (out == null) {
|
||||||
|
return "./front";
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getBackupFolder() {
|
||||||
|
final String out = System.getenv(BASE_NAME + "BACKUP_FOLDER");
|
||||||
|
if (out == null) {
|
||||||
|
return "./backup";
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isInitWithBackup() {
|
||||||
|
final String out = System.getenv(BASE_NAME + "INIT_WITH_BACKUP");
|
||||||
|
if (out == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return "true".equals(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
package org.kar.karideo.api;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
|
||||||
import org.kar.archidata.dataAccess.QueryAnd;
|
|
||||||
import org.kar.archidata.dataAccess.QueryCondition;
|
|
||||||
import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
|
|
||||||
import org.kar.archidata.dataAccess.options.Condition;
|
|
||||||
import org.kar.archidata.tools.DataTools;
|
|
||||||
import org.kar.karideo.model.Season;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
|
||||||
import jakarta.ws.rs.Consumes;
|
|
||||||
import jakarta.ws.rs.DELETE;
|
|
||||||
import jakarta.ws.rs.GET;
|
|
||||||
import jakarta.ws.rs.PATCH;
|
|
||||||
import jakarta.ws.rs.POST;
|
|
||||||
import jakarta.ws.rs.Path;
|
|
||||||
import jakarta.ws.rs.PathParam;
|
|
||||||
import jakarta.ws.rs.Produces;
|
|
||||||
import jakarta.ws.rs.core.MediaType;
|
|
||||||
import jakarta.ws.rs.core.Response;
|
|
||||||
|
|
||||||
@Path("/season")
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public class SeasonResource {
|
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(SeasonResource.class);
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
public static Season getWithId(@PathParam("id") final Long id) throws Exception {
|
|
||||||
return DataAccess.get(Season.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
public List<Season> get() throws Exception {
|
|
||||||
return DataAccess.gets(Season.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public Season get(@PathParam("id") final Long id) throws Exception {
|
|
||||||
return DataAccess.get(Season.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =============================================================================
|
|
||||||
* ADMIN SECTION:
|
|
||||||
* ============================================================================= */
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public Season put(final String jsonRequest) throws Exception {
|
|
||||||
return DataAccess.insertWithJson(Season.class, jsonRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PATCH
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public Season put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
|
|
||||||
DataAccess.updateWithJson(Season.class, id, jsonRequest);
|
|
||||||
return DataAccess.get(Season.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@DELETE
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
public Response delete(@PathParam("id") final Long id) throws Exception {
|
|
||||||
DataAccess.delete(Season.class, id);
|
|
||||||
return Response.ok().build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("{id}/add_cover")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
|
||||||
public Response uploadCover(@PathParam("id") final Long id, @FormDataParam("fileName") final String fileName, @FormDataParam("file") final InputStream fileInputStream,
|
|
||||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData) {
|
|
||||||
return DataTools.uploadCover(Season.class, id, fileName, fileInputStream, fileMetaData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}/rm_cover/{coverId}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
public Response removeCover(@PathParam("id") final Long id, @PathParam("coverId") final Long coverId) throws Exception {
|
|
||||||
AddOnManyToMany.removeLink(Season.class, id, "cover", coverId);
|
|
||||||
return Response.ok(DataAccess.get(Season.class, id)).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Season getOrCreate(final String name, final Long seriesId) {
|
|
||||||
try {
|
|
||||||
Season out = DataAccess.getWhere(Season.class, new Condition(new QueryAnd(new QueryCondition("name", "=", name), new QueryCondition("parentId", "=", seriesId))));
|
|
||||||
if (out == null) {
|
|
||||||
out = new Season();
|
|
||||||
out.name = name;
|
|
||||||
out.parentId = seriesId;
|
|
||||||
out = DataAccess.insert(out);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
} catch (final Exception e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
package org.kar.karideo.api;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
|
||||||
import org.kar.archidata.dataAccess.QueryAnd;
|
|
||||||
import org.kar.archidata.dataAccess.QueryCondition;
|
|
||||||
import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
|
|
||||||
import org.kar.archidata.dataAccess.options.Condition;
|
|
||||||
import org.kar.archidata.tools.DataTools;
|
|
||||||
import org.kar.karideo.model.Series;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
|
||||||
import jakarta.ws.rs.Consumes;
|
|
||||||
import jakarta.ws.rs.DELETE;
|
|
||||||
import jakarta.ws.rs.GET;
|
|
||||||
import jakarta.ws.rs.PATCH;
|
|
||||||
import jakarta.ws.rs.POST;
|
|
||||||
import jakarta.ws.rs.Path;
|
|
||||||
import jakarta.ws.rs.PathParam;
|
|
||||||
import jakarta.ws.rs.Produces;
|
|
||||||
import jakarta.ws.rs.core.MediaType;
|
|
||||||
import jakarta.ws.rs.core.Response;
|
|
||||||
|
|
||||||
@Path("/series")
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public class SeriesResource {
|
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(SeriesResource.class);
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
public static Series getWithId(@PathParam("id") final Long id) throws Exception {
|
|
||||||
return DataAccess.get(Series.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
public List<Series> get() throws Exception {
|
|
||||||
return DataAccess.gets(Series.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public Series get(@PathParam("id") final Long id) throws Exception {
|
|
||||||
return DataAccess.get(Series.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =============================================================================
|
|
||||||
* ADMIN SECTION:
|
|
||||||
* ============================================================================= */
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public Series put(final String jsonRequest) throws Exception {
|
|
||||||
return DataAccess.insertWithJson(Series.class, jsonRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PATCH
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public Series put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
|
|
||||||
DataAccess.updateWithJson(Series.class, id, jsonRequest);
|
|
||||||
return DataAccess.get(Series.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@DELETE
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
public Response delete(@PathParam("id") final Long id) throws Exception {
|
|
||||||
DataAccess.delete(Series.class, id);
|
|
||||||
return Response.ok().build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("{id}/add_cover")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
|
||||||
public Response uploadCover(@PathParam("id") final Long id, @FormDataParam("fileName") final String fileName, @FormDataParam("file") final InputStream fileInputStream,
|
|
||||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData) {
|
|
||||||
return DataTools.uploadCover(Series.class, id, fileName, fileInputStream, fileMetaData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}/rm_cover/{coverId}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
public Response removeCover(@PathParam("id") final Long id, @PathParam("coverId") final Long coverId) throws Exception {
|
|
||||||
AddOnManyToMany.removeLink(Series.class, id, "cover", coverId);
|
|
||||||
return Response.ok(DataAccess.get(Series.class, id)).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Series getOrCreate(final String name, final Long typeId) {
|
|
||||||
try {
|
|
||||||
Series out = DataAccess.getWhere(Series.class, new Condition(new QueryAnd(new QueryCondition("name", "=", name), new QueryCondition("parentId", "=", typeId))));
|
|
||||||
if (out == null) {
|
|
||||||
out = new Series();
|
|
||||||
out.name = name;
|
|
||||||
out.parentId = typeId;
|
|
||||||
out = DataAccess.insert(out);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
} catch (final Exception e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
package org.kar.karideo.api;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
|
||||||
import org.kar.archidata.dataAccess.QueryCondition;
|
|
||||||
import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
|
|
||||||
import org.kar.archidata.dataAccess.options.Condition;
|
|
||||||
import org.kar.archidata.tools.DataTools;
|
|
||||||
import org.kar.karideo.model.Type;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
|
||||||
import jakarta.ws.rs.Consumes;
|
|
||||||
import jakarta.ws.rs.DELETE;
|
|
||||||
import jakarta.ws.rs.GET;
|
|
||||||
import jakarta.ws.rs.PATCH;
|
|
||||||
import jakarta.ws.rs.POST;
|
|
||||||
import jakarta.ws.rs.Path;
|
|
||||||
import jakarta.ws.rs.PathParam;
|
|
||||||
import jakarta.ws.rs.Produces;
|
|
||||||
import jakarta.ws.rs.core.MediaType;
|
|
||||||
import jakarta.ws.rs.core.Response;
|
|
||||||
|
|
||||||
@Path("/type")
|
|
||||||
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
|
|
||||||
public class TypeResource {
|
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(TypeResource.class);
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
public static Type getWithId(@PathParam("id") final Long id) throws Exception {
|
|
||||||
return DataAccess.get(Type.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
public List<Type> get() throws Exception {
|
|
||||||
return DataAccess.gets(Type.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public Type get(@PathParam("id") final Long id) throws Exception {
|
|
||||||
return DataAccess.get(Type.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Type getId(final Long id) throws Exception {
|
|
||||||
return DataAccess.get(Type.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =============================================================================
|
|
||||||
* ADMIN SECTION:
|
|
||||||
* ============================================================================= */
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public Type put(final String jsonRequest) throws Exception {
|
|
||||||
return DataAccess.insertWithJson(Type.class, jsonRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PATCH
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public Type put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
|
|
||||||
DataAccess.updateWithJson(Type.class, id, jsonRequest);
|
|
||||||
return DataAccess.get(Type.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@DELETE
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
public Response delete(@PathParam("id") final Long id) throws Exception {
|
|
||||||
DataAccess.delete(Type.class, id);
|
|
||||||
return Response.ok().build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("{id}/add_cover")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
|
||||||
public Response uploadCover(@PathParam("id") final Long id, @FormDataParam("fileName") final String fileName, @FormDataParam("file") final InputStream fileInputStream,
|
|
||||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData) {
|
|
||||||
return DataTools.uploadCover(Type.class, id, fileName, fileInputStream, fileMetaData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}/rm_cover/{coverId}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
public Response removeCover(@PathParam("id") final Long id, @PathParam("coverId") final Long coverId) throws Exception {
|
|
||||||
AddOnManyToMany.removeLink(Type.class, id, "cover", coverId);
|
|
||||||
return Response.ok(DataAccess.get(Type.class, id)).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Type getOrCreate(final String name) {
|
|
||||||
try {
|
|
||||||
Type out = DataAccess.getWhere(Type.class, new Condition(new QueryCondition("name", "=", name)));
|
|
||||||
if (out == null) {
|
|
||||||
out = new Type();
|
|
||||||
out.name = name;
|
|
||||||
out = DataAccess.insert(out);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
} catch (final Exception e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
package org.kar.karideo.api;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
|
||||||
import org.kar.archidata.dataAccess.QueryAnd;
|
|
||||||
import org.kar.archidata.dataAccess.QueryCondition;
|
|
||||||
import org.kar.archidata.dataAccess.options.Condition;
|
|
||||||
import org.kar.archidata.filter.GenericContext;
|
|
||||||
import org.kar.karideo.model.UserMediaAdvancement;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
|
||||||
import jakarta.ws.rs.Consumes;
|
|
||||||
import jakarta.ws.rs.DELETE;
|
|
||||||
import jakarta.ws.rs.GET;
|
|
||||||
import jakarta.ws.rs.PATCH;
|
|
||||||
import jakarta.ws.rs.Path;
|
|
||||||
import jakarta.ws.rs.PathParam;
|
|
||||||
import jakarta.ws.rs.Produces;
|
|
||||||
import jakarta.ws.rs.core.Context;
|
|
||||||
import jakarta.ws.rs.core.MediaType;
|
|
||||||
import jakarta.ws.rs.core.Response;
|
|
||||||
import jakarta.ws.rs.core.SecurityContext;
|
|
||||||
|
|
||||||
@Path("/advancement")
|
|
||||||
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
|
|
||||||
public class UserMediaAdvancementResource {
|
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(UserMediaAdvancementResource.class);
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
public UserMediaAdvancement getWithId(@Context final SecurityContext sc, @PathParam("id") final Long id) throws Exception {
|
|
||||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
|
||||||
return DataAccess.getWhere(UserMediaAdvancement.class, new Condition(new QueryAnd(new QueryCondition("mediaId", "=", id), new QueryCondition("userId", "=", gc.userByToken.id))));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
public List<UserMediaAdvancement> gets(@Context final SecurityContext sc) throws Exception {
|
|
||||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
|
||||||
return DataAccess.getsWhere(UserMediaAdvancement.class, new Condition(new QueryCondition("userId", "=", gc.userByToken.id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =============================================================================
|
|
||||||
* Modification SECTION:
|
|
||||||
* ============================================================================= */
|
|
||||||
|
|
||||||
public record MediaInformations(
|
|
||||||
int time,
|
|
||||||
float percent,
|
|
||||||
int count) {}
|
|
||||||
|
|
||||||
//@POST
|
|
||||||
//@Path("{id}")
|
|
||||||
//@RolesAllowed("USER")
|
|
||||||
//@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public UserMediaAdvancement post(@Context final SecurityContext sc, @PathParam("id") final Long id, final MediaInformations data) throws Exception {
|
|
||||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
|
||||||
final UserMediaAdvancement elem = new UserMediaAdvancement();
|
|
||||||
elem.userId = gc.userByToken.id;
|
|
||||||
elem.mediaId = id;
|
|
||||||
elem.time = data.time;
|
|
||||||
elem.percent = data.percent;
|
|
||||||
elem.count = data.count;
|
|
||||||
return DataAccess.insert(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
public record MediaInformationsDelta(
|
|
||||||
int time,
|
|
||||||
float percent,
|
|
||||||
boolean addCount) {}
|
|
||||||
|
|
||||||
@PATCH
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public UserMediaAdvancement put(@Context final SecurityContext sc, @PathParam("id") final Long id, final MediaInformationsDelta data) throws Exception {
|
|
||||||
final UserMediaAdvancement elem = getWithId(sc, id);
|
|
||||||
if (elem == null) {
|
|
||||||
// insert element
|
|
||||||
if (data.addCount) {
|
|
||||||
return post(sc, id, new MediaInformations(data.time(), data.percent(), 1));
|
|
||||||
} else {
|
|
||||||
return post(sc, id, new MediaInformations(data.time(), data.percent(), 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elem.time = data.time;
|
|
||||||
elem.percent = data.percent;
|
|
||||||
if (data.addCount) {
|
|
||||||
elem.count++;
|
|
||||||
}
|
|
||||||
LOGGER.info("{},{},{}", elem.time, elem.percent, elem.count);
|
|
||||||
final int nbAfected = DataAccess.update(elem, elem.id, List.of("time", "percent", "count"));
|
|
||||||
return DataAccess.get(UserMediaAdvancement.class, elem.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@DELETE
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
public Response delete(@Context final SecurityContext sc, @PathParam("id") final Long id) throws Exception {
|
|
||||||
final UserMediaAdvancement elem = getWithId(sc, id);
|
|
||||||
DataAccess.delete(UserMediaAdvancement.class, elem.id);
|
|
||||||
return Response.ok().build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,223 +0,0 @@
|
|||||||
package org.kar.karideo.api;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
|
||||||
import org.kar.archidata.api.DataResource;
|
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
|
||||||
import org.kar.archidata.dataAccess.addOn.AddOnManyToMany;
|
|
||||||
import org.kar.archidata.exception.FailException;
|
|
||||||
import org.kar.archidata.exception.InputException;
|
|
||||||
import org.kar.archidata.model.Data;
|
|
||||||
import org.kar.archidata.tools.DataTools;
|
|
||||||
import org.kar.karideo.model.Media;
|
|
||||||
import org.kar.karideo.model.Season;
|
|
||||||
import org.kar.karideo.model.Series;
|
|
||||||
import org.kar.karideo.model.Type;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
|
||||||
import jakarta.ws.rs.Consumes;
|
|
||||||
import jakarta.ws.rs.DELETE;
|
|
||||||
import jakarta.ws.rs.GET;
|
|
||||||
import jakarta.ws.rs.PATCH;
|
|
||||||
import jakarta.ws.rs.POST;
|
|
||||||
import jakarta.ws.rs.Path;
|
|
||||||
import jakarta.ws.rs.PathParam;
|
|
||||||
import jakarta.ws.rs.Produces;
|
|
||||||
import jakarta.ws.rs.core.MediaType;
|
|
||||||
import jakarta.ws.rs.core.Response;
|
|
||||||
|
|
||||||
@Path("/video")
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public class VideoResource {
|
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(VideoResource.class);
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
public List<Media> get() throws Exception {
|
|
||||||
return DataAccess.gets(Media.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("USER")
|
|
||||||
public Media get(@PathParam("id") final Long id) throws Exception {
|
|
||||||
return DataAccess.get(Media.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PATCH
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
public Media put(@PathParam("id") final Long id, final String jsonRequest) throws Exception {
|
|
||||||
System.out.println("update video " + id + " ==> '" + jsonRequest + "'");
|
|
||||||
DataAccess.updateWithJson(Media.class, id, jsonRequest);
|
|
||||||
return DataAccess.get(Media.class, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String multipartCorrection(final String data) {
|
|
||||||
if (data == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (data.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (data.contentEquals("null")) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("/upload/")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
|
||||||
public Response uploadFile(@FormDataParam("fileName") String fileName, @FormDataParam("universe") String universe, @FormDataParam("series") String series,
|
|
||||||
//@FormDataParam("seriesId") String seriesId, Not used ...
|
|
||||||
@FormDataParam("season") String season, @FormDataParam("episode") String episode, @FormDataParam("title") String title, @FormDataParam("typeId") String typeId,
|
|
||||||
@FormDataParam("file") final InputStream fileInputStream, @FormDataParam("file") final FormDataContentDisposition fileMetaData) throws FailException {
|
|
||||||
try {
|
|
||||||
// correct input string stream :
|
|
||||||
fileName = multipartCorrection(fileName);
|
|
||||||
universe = multipartCorrection(universe);
|
|
||||||
series = multipartCorrection(series);
|
|
||||||
season = multipartCorrection(season);
|
|
||||||
episode = multipartCorrection(episode);
|
|
||||||
title = multipartCorrection(title);
|
|
||||||
typeId = multipartCorrection(typeId);
|
|
||||||
|
|
||||||
//public NodeSmall uploadFile(final FormDataMultiPart form) {
|
|
||||||
System.out.println("Upload media file: " + fileMetaData);
|
|
||||||
System.out.println(" - fileName: " + fileName);
|
|
||||||
System.out.println(" - universe: " + universe);
|
|
||||||
System.out.println(" - series: " + series);
|
|
||||||
System.out.println(" - season: " + season);
|
|
||||||
System.out.println(" - episode: " + episode);
|
|
||||||
System.out.println(" - title: " + title);
|
|
||||||
System.out.println(" - type: " + typeId);
|
|
||||||
System.out.println(" - fileInputStream: " + fileInputStream);
|
|
||||||
System.out.println(" - fileMetaData: " + fileMetaData);
|
|
||||||
System.out.flush();
|
|
||||||
if (typeId == null) {
|
|
||||||
throw new InputException("typeId", "TypiId is not specified");
|
|
||||||
}
|
|
||||||
|
|
||||||
final long tmpUID = DataResource.getTmpDataId();
|
|
||||||
final String sha512 = DataResource.saveTemporaryFile(fileInputStream, tmpUID);
|
|
||||||
Data data = DataResource.getWithSha512(sha512);
|
|
||||||
if (data == null) {
|
|
||||||
System.out.println("Need to add the data in the BDD ... ");
|
|
||||||
System.out.flush();
|
|
||||||
try {
|
|
||||||
data = DataResource.createNewData(tmpUID, fileName, sha512);
|
|
||||||
} catch (final IOException ex) {
|
|
||||||
DataResource.removeTemporaryFile(tmpUID);
|
|
||||||
ex.printStackTrace();
|
|
||||||
throw new FailException("can not create input media (the data model has an internal error");
|
|
||||||
}
|
|
||||||
} else if (data.deleted) {
|
|
||||||
System.out.println("Data already exist but deleted");
|
|
||||||
System.out.flush();
|
|
||||||
DataResource.undelete(data.id);
|
|
||||||
data.deleted = false;
|
|
||||||
} else {
|
|
||||||
System.out.println("Data already exist ... all good");
|
|
||||||
System.out.flush();
|
|
||||||
}
|
|
||||||
// Fist step: retive all the Id of each parents:...
|
|
||||||
System.out.println("Find typeNode");
|
|
||||||
// check if id of type exist:
|
|
||||||
final Type typeNode = TypeResource.getId(Long.parseLong(typeId));
|
|
||||||
if (typeNode == null) {
|
|
||||||
DataResource.removeTemporaryFile(tmpUID);
|
|
||||||
throw new InputException("typeId", "TypeId does not exist ...");
|
|
||||||
}
|
|
||||||
System.out.println(" ==> " + typeNode);
|
|
||||||
System.out.println("Find seriesNode");
|
|
||||||
// get uid of group:
|
|
||||||
Series seriesNode = null;
|
|
||||||
if (series != null) {
|
|
||||||
seriesNode = SeriesResource.getOrCreate(series, typeNode.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println(" ==> " + seriesNode);
|
|
||||||
System.out.println("Find seasonNode");
|
|
||||||
// get uid of season:
|
|
||||||
Season seasonNode = null;
|
|
||||||
if (seriesNode == null && season != null) {
|
|
||||||
DataResource.removeTemporaryFile(tmpUID);
|
|
||||||
throw new InputException("season", "Season is set but no seraies is set !!");
|
|
||||||
}
|
|
||||||
if (season != null) {
|
|
||||||
seasonNode = SeasonResource.getOrCreate(season, seriesNode.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println(" ==> " + seasonNode);
|
|
||||||
System.out.println("add media");
|
|
||||||
|
|
||||||
final long uniqueSQLID = -1;
|
|
||||||
try {
|
|
||||||
final Media media = new Media();
|
|
||||||
media.name = title;
|
|
||||||
media.dataId = data.id;
|
|
||||||
media.typeId = typeNode.id;
|
|
||||||
media.seriesId = null;
|
|
||||||
if (seriesNode != null) {
|
|
||||||
media.seriesId = seriesNode.id;
|
|
||||||
}
|
|
||||||
media.seasonId = null;
|
|
||||||
if (seasonNode != null) {
|
|
||||||
media.seasonId = seasonNode.id;
|
|
||||||
}
|
|
||||||
media.episode = null;
|
|
||||||
if (episode != null && !episode.contentEquals("")) {
|
|
||||||
media.episode = Integer.parseInt(episode);
|
|
||||||
}
|
|
||||||
final Media out = DataAccess.insert(media);
|
|
||||||
DataResource.removeTemporaryFile(tmpUID);
|
|
||||||
System.out.println("uploaded .... compleate: " + uniqueSQLID);
|
|
||||||
final Media creation = get(uniqueSQLID);
|
|
||||||
return Response.ok(creation).build();
|
|
||||||
} catch (final SQLException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
System.out.println("Catch error:" + ex.getMessage());
|
|
||||||
throw new FailException("Catch SQLerror ==> check server logs");
|
|
||||||
}
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
System.out.println("Catch an unexpected error ... " + ex.getMessage());
|
|
||||||
ex.printStackTrace();
|
|
||||||
throw new FailException("Catch Exception ==> check server logs");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("{id}/add_cover")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
|
||||||
public Response uploadCover(@PathParam("id") final Long id, @FormDataParam("fileName") final String fileName, @FormDataParam("file") final InputStream fileInputStream,
|
|
||||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData) {
|
|
||||||
return DataTools.uploadCover(Media.class, id, fileName, fileInputStream, fileMetaData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{id}/rm_cover/{coverId}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
public Response removeCover(@PathParam("id") final Long id, @PathParam("coverId") final Long coverId) throws Exception {
|
|
||||||
AddOnManyToMany.removeLink(Media.class, id, "cover", coverId);
|
|
||||||
return Response.ok(DataAccess.get(Media.class, id)).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@DELETE
|
|
||||||
@Path("{id}")
|
|
||||||
@RolesAllowed("ADMIN")
|
|
||||||
public Response delete(@PathParam("id") final Long id) throws Exception {
|
|
||||||
DataAccess.delete(Media.class, id);
|
|
||||||
return Response.ok().build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package org.kar.karideo.internal;
|
|
||||||
|
|
||||||
//import io.scenarium.logger.LogLevel;
|
|
||||||
//import io.scenarium.logger.Logger;
|
|
||||||
|
|
||||||
public class Log {
|
|
||||||
// private static final String LIB_NAME = "logger";
|
|
||||||
// private static final String LIB_NAME_DRAW = Logger.getDrawableName(LIB_NAME);
|
|
||||||
// private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(LIB_NAME, LogLevel.CRITICAL);
|
|
||||||
// private static final boolean PRINT_ERROR = Logger.getNeedPrint(LIB_NAME, LogLevel.ERROR);
|
|
||||||
// private static final boolean PRINT_WARNING = Logger.getNeedPrint(LIB_NAME, LogLevel.WARNING);
|
|
||||||
// private static final boolean PRINT_INFO = Logger.getNeedPrint(LIB_NAME, LogLevel.INFO);
|
|
||||||
// private static final boolean PRINT_DEBUG = Logger.getNeedPrint(LIB_NAME, LogLevel.DEBUG);
|
|
||||||
// private static final boolean PRINT_VERBOSE = Logger.getNeedPrint(LIB_NAME, LogLevel.VERBOSE);
|
|
||||||
// private static final boolean PRINT_TODO = Logger.getNeedPrint(LIB_NAME, LogLevel.TODO);
|
|
||||||
// private static final boolean PRINT_PRINT = Logger.getNeedPrint(LIB_NAME, LogLevel.PRINT);
|
|
||||||
//
|
|
||||||
// private Log() {}
|
|
||||||
//
|
|
||||||
// public static void print(String data) {
|
|
||||||
// if (PRINT_PRINT)
|
|
||||||
// Logger.print(LIB_NAME_DRAW, data);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static void todo(String data) {
|
|
||||||
// if (PRINT_TODO)
|
|
||||||
// Logger.todo(LIB_NAME_DRAW, data);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static void critical(String data) {
|
|
||||||
// if (PRINT_CRITICAL)
|
|
||||||
// Logger.critical(LIB_NAME_DRAW, data);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static void error(String data) {
|
|
||||||
// if (PRINT_ERROR)
|
|
||||||
// Logger.error(LIB_NAME_DRAW, data);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static void warning(String data) {
|
|
||||||
// if (PRINT_WARNING)
|
|
||||||
// Logger.warning(LIB_NAME_DRAW, data);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static void info(String data) {
|
|
||||||
// if (PRINT_INFO)
|
|
||||||
// Logger.info(LIB_NAME_DRAW, data);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static void debug(String data) {
|
|
||||||
// if (PRINT_DEBUG)
|
|
||||||
// Logger.debug(LIB_NAME_DRAW, data);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static void verbose(String data) {
|
|
||||||
// if (PRINT_VERBOSE)
|
|
||||||
// Logger.verbose(LIB_NAME_DRAW, data);
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
package org.kar.karideo.migration;
|
|
||||||
|
|
||||||
import org.kar.archidata.migration.MigrationSqlStep;
|
|
||||||
import org.kar.archidata.model.Data;
|
|
||||||
import org.kar.archidata.model.User;
|
|
||||||
import org.kar.karideo.model.Media;
|
|
||||||
import org.kar.karideo.model.Season;
|
|
||||||
import org.kar.karideo.model.Series;
|
|
||||||
import org.kar.karideo.model.Type;
|
|
||||||
import org.kar.karideo.model.UserMediaAdvancement;
|
|
||||||
|
|
||||||
public class Initialization extends MigrationSqlStep {
|
|
||||||
|
|
||||||
public static final int KARSO_INITIALISATION_ID = 1;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "Initialization";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Initialization() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateStep() throws Exception {
|
|
||||||
addClass(Data.class);
|
|
||||||
addClass(Media.class);
|
|
||||||
addClass(Type.class);
|
|
||||||
addClass(Series.class);
|
|
||||||
addClass(Season.class);
|
|
||||||
addClass(User.class);
|
|
||||||
addClass(UserMediaAdvancement.class);
|
|
||||||
|
|
||||||
addAction("""
|
|
||||||
INSERT INTO `type` (`id`, `name`, `description`) VALUES
|
|
||||||
(1, 'Documentary', 'Documentary (animals, space, earth...)'),
|
|
||||||
(2, 'Movie', 'Movie with real humans (film)'),
|
|
||||||
(3, 'Animation', 'Animation movies (film)'),
|
|
||||||
(4, 'Short movie', 'Small movies (less 2 minutes)'),
|
|
||||||
(5, 'TV show', 'TV show for old peoples'),
|
|
||||||
(6, 'Animation TV show', 'TV show for young peoples'),
|
|
||||||
(7, 'Theater', 'Theater play'),
|
|
||||||
(8, 'One man show', 'Recorded stand up'),
|
|
||||||
(9, 'Concert', 'Recorded concert'),
|
|
||||||
(10, 'Opera', 'Recorded opera');
|
|
||||||
""");
|
|
||||||
// set start increment element to permit to add after default elements
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `data` AUTO_INCREMENT = 1000;
|
|
||||||
""", "mysql");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `media` AUTO_INCREMENT = 1000;
|
|
||||||
""", "mysql");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `type` AUTO_INCREMENT = 1000;
|
|
||||||
""", "mysql");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `series` AUTO_INCREMENT = 1000;
|
|
||||||
""", "mysql");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `season` AUTO_INCREMENT = 1000;
|
|
||||||
""", "mysql");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `userMediaAdvancement` AUTO_INCREMENT = 1000;
|
|
||||||
""", "mysql");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package org.kar.karideo.migration;
|
|
||||||
|
|
||||||
import org.kar.archidata.migration.MigrationSqlStep;
|
|
||||||
import org.kar.karideo.model.UserMediaAdvancement;
|
|
||||||
|
|
||||||
public class Migration20230810 extends MigrationSqlStep {
|
|
||||||
|
|
||||||
public static final int KARSO_INITIALISATION_ID = 1;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "migration-2023-08-10";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Migration20230810() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateStep() throws Exception {
|
|
||||||
addClass(UserMediaAdvancement.class);
|
|
||||||
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `userMediaAdvancement` AUTO_INCREMENT = 1000;
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package org.kar.karideo.migration;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.kar.archidata.migration.MigrationSqlStep;
|
|
||||||
|
|
||||||
public class Migration20231015 extends MigrationSqlStep {
|
|
||||||
|
|
||||||
public static final int KARSO_INITIALISATION_ID = 1;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "migration-2023-10-15: refactor creation and update time";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Migration20231015() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateStep() throws Exception {
|
|
||||||
for (String elem : List.of("data", "media", "media_link_cover", "season", "season_link_cover", "series", "series_link_cover", "type", "type_link_cover", "user", "userMediaAdvancement")) {
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `""" + elem + """
|
|
||||||
`
|
|
||||||
RENAME COLUMN `create_date` TO `createdAt`,
|
|
||||||
RENAME COLUMN `modify_date` TO `updatedAt`;
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
display();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
package org.kar.karideo.migration;
|
|
||||||
|
|
||||||
import org.kar.archidata.migration.MigrationSqlStep;
|
|
||||||
|
|
||||||
public class Migration20231126 extends MigrationSqlStep {
|
|
||||||
|
|
||||||
public static final int KARSO_INITIALISATION_ID = 1;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "migration-2023-11-26: re-order the migration for the new API of archidata";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Migration20231126() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateStep() throws Exception {
|
|
||||||
|
|
||||||
// update migration update (last one)
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `KAR_migration`
|
|
||||||
CHANGE `id` `id` bigint NOT NULL COMMENT 'Primary key of the base' AUTO_INCREMENT FIRST,
|
|
||||||
CHANGE `create_date` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'Create time of the object' AFTER `id`,
|
|
||||||
CHANGE `modify_date` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'When update the object' AFTER `createdAt`,
|
|
||||||
CHANGE `deleted` `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'When delete, they are not removed, they are just set in a deleted state' AFTER `updatedAt`,
|
|
||||||
ADD `version` int NOT NULL DEFAULT '2' AFTER `deleted`,
|
|
||||||
CHANGE `name` `name` varchar(256) COLLATE 'utf8mb4_0900_ai_ci' NULL COMMENT 'Name of the migration' AFTER `version`,
|
|
||||||
CHANGE `terminated` `terminated` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'if the migration is well terminated or not' AFTER `name`,
|
|
||||||
CHANGE `stepId` `stepId` int NULL COMMENT 'index in the migration progression' AFTER `terminated`,
|
|
||||||
CHANGE `count` `count` int NULL COMMENT 'number of element in the migration' AFTER `stepId`,
|
|
||||||
CHANGE `log` `log` text COLLATE 'utf8mb3_general_ci' NULL COMMENT 'Log generate by the migration' AFTER `count`;
|
|
||||||
""");
|
|
||||||
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `data`
|
|
||||||
CHANGE `id` `id` bigint NOT NULL COMMENT 'Primary key of the base' AUTO_INCREMENT FIRST,
|
|
||||||
CHANGE `createdAt` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'Create time of the object' AFTER `id`,
|
|
||||||
CHANGE `updatedAt` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'When update the object' AFTER `createdAt`,
|
|
||||||
CHANGE `deleted` `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'When delete, they are not removed, they are just set in a deleted state' AFTER `updatedAt`,
|
|
||||||
CHANGE `sha512` `sha512` varchar(128) COLLATE 'utf8mb4_0900_ai_ci' NOT NULL COMMENT 'Sha512 of the data' AFTER `deleted`,
|
|
||||||
CHANGE `mimeType` `mimeType` varchar(128) COLLATE 'utf8mb4_0900_ai_ci' NOT NULL COMMENT 'Mime -type of the media' AFTER `sha512`,
|
|
||||||
CHANGE `size` `size` bigint NOT NULL COMMENT 'Size in Byte of the data' AFTER `mimeType`;
|
|
||||||
""");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `media`
|
|
||||||
CHANGE `id` `id` bigint NOT NULL COMMENT 'Primary key of the base' AUTO_INCREMENT FIRST,
|
|
||||||
CHANGE `createdAt` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'Create time of the object' AFTER `id`,
|
|
||||||
CHANGE `updatedAt` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'When update the object' AFTER `createdAt`,
|
|
||||||
CHANGE `deleted` `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'When delete, they are not removed, they are just set in a deleted state' AFTER `updatedAt`,
|
|
||||||
CHANGE `name` `name` text COLLATE 'utf8mb3_general_ci' NOT NULL COMMENT 'Name of the media (this represent the title)' AFTER `deleted`,
|
|
||||||
CHANGE `description` `description` text COLLATE 'utf8mb3_general_ci' NULL COMMENT 'Description of the media' AFTER `name`,
|
|
||||||
CHANGE `dataId` `dataId` bigint NOT NULL COMMENT 'Foreign Key Id of the data' AFTER `description`,
|
|
||||||
CHANGE `typeId` `typeId` bigint NULL COMMENT 'Type of the media' AFTER `dataId`,
|
|
||||||
CHANGE `seriesId` `seriesId` bigint NULL COMMENT 'Series reference of the media' AFTER `typeId`,
|
|
||||||
CHANGE `seasonId` `seasonId` bigint NULL COMMENT 'Saison reference of the media' AFTER `seriesId`,
|
|
||||||
CHANGE `episode` `episode` int NULL COMMENT 'Episide Id' AFTER `seasonId`,
|
|
||||||
CHANGE `date` `date` int NULL AFTER `episode`,
|
|
||||||
CHANGE `time` `time` int NULL COMMENT 'Creation years of the media' AFTER `date`,
|
|
||||||
CHANGE `ageLimit` `ageLimit` int NULL COMMENT 'Limitation Age of the media' AFTER `time`;
|
|
||||||
""");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `media_link_cover`
|
|
||||||
CHANGE `createdAt` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) AFTER `id`,
|
|
||||||
CHANGE `updatedAt` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) AFTER `createdAt`,
|
|
||||||
CHANGE `deleted` `deleted` tinyint(1) NOT NULL DEFAULT '0' AFTER `updatedAt`,
|
|
||||||
CHANGE `media_id` `object1id` bigint NOT NULL AFTER `deleted`,
|
|
||||||
CHANGE `cover_id` `object2id` bigint NOT NULL AFTER `object1id`;
|
|
||||||
""");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `season`
|
|
||||||
CHANGE `id` `id` bigint NOT NULL COMMENT 'Primary key of the base' AUTO_INCREMENT FIRST,
|
|
||||||
CHANGE `createdAt` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'Create time of the object' AFTER `id`,
|
|
||||||
CHANGE `updatedAt` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'When update the object' AFTER `createdAt`,
|
|
||||||
CHANGE `deleted` `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'When delete, they are not removed, they are just set in a deleted state' AFTER `updatedAt`,
|
|
||||||
CHANGE `name` `name` text COLLATE 'utf8mb3_general_ci' NOT NULL COMMENT 'Name of the media (this represent the title)' AFTER `deleted`,
|
|
||||||
CHANGE `description` `description` text COLLATE 'utf8mb3_general_ci' NULL COMMENT 'Description of the media' AFTER `name`,
|
|
||||||
CHANGE `parentId` `parentId` bigint NOT NULL COMMENT 'series parent ID' AFTER `description`;
|
|
||||||
""");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `season_link_cover`
|
|
||||||
CHANGE `createdAt` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) AFTER `id`,
|
|
||||||
CHANGE `updatedAt` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) AFTER `createdAt`,
|
|
||||||
CHANGE `deleted` `deleted` tinyint(1) NOT NULL DEFAULT '0' AFTER `updatedAt`,
|
|
||||||
CHANGE `season_id` `object1id` bigint NOT NULL AFTER `deleted`,
|
|
||||||
CHANGE `cover_id` `object2id` bigint NOT NULL AFTER `object1id`;
|
|
||||||
""");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `series`
|
|
||||||
CHANGE `id` `id` bigint NOT NULL COMMENT 'Primary key of the base' AUTO_INCREMENT FIRST,
|
|
||||||
CHANGE `createdAt` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'Create time of the object' AFTER `id`,
|
|
||||||
CHANGE `updatedAt` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'When update the object' AFTER `createdAt`,
|
|
||||||
CHANGE `deleted` `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'When delete, they are not removed, they are just set in a deleted state' AFTER `updatedAt`,
|
|
||||||
CHANGE `name` `name` text COLLATE 'utf8mb3_general_ci' NOT NULL COMMENT 'Name of the media (this represent the title)' AFTER `deleted`,
|
|
||||||
CHANGE `description` `description` text COLLATE 'utf8mb3_general_ci' NULL COMMENT 'Description of the media' AFTER `name`,
|
|
||||||
CHANGE `parentId` `parentId` bigint NOT NULL COMMENT 'series parent ID' AFTER `description`;
|
|
||||||
""");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `series_link_cover`
|
|
||||||
CHANGE `createdAt` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) AFTER `id`,
|
|
||||||
CHANGE `updatedAt` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) AFTER `createdAt`,
|
|
||||||
CHANGE `deleted` `deleted` tinyint(1) NOT NULL DEFAULT '0' AFTER `updatedAt`,
|
|
||||||
CHANGE `series_id` `object1id` bigint NOT NULL AFTER `deleted`,
|
|
||||||
CHANGE `cover_id` `object2id` bigint NOT NULL AFTER `object1id`;
|
|
||||||
""");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `type`
|
|
||||||
CHANGE `id` `id` bigint NOT NULL COMMENT 'Primary key of the base' AUTO_INCREMENT FIRST,
|
|
||||||
CHANGE `createdAt` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'Create time of the object' AFTER `id`,
|
|
||||||
CHANGE `updatedAt` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'When update the object' AFTER `createdAt`,
|
|
||||||
CHANGE `name` `name` text COLLATE 'utf8mb3_general_ci' NOT NULL COMMENT 'Name of the media (this represent the title)' AFTER `deleted`,
|
|
||||||
CHANGE `description` `description` text COLLATE 'utf8mb3_general_ci' NULL COMMENT 'Description of the media' AFTER `name`;
|
|
||||||
""");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `type_link_cover`
|
|
||||||
CHANGE `createdAt` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) AFTER `id`,
|
|
||||||
CHANGE `updatedAt` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) AFTER `createdAt`,
|
|
||||||
CHANGE `deleted` `deleted` tinyint(1) NOT NULL DEFAULT '0' AFTER `updatedAt`,
|
|
||||||
CHANGE `type_id` `object1id` bigint NOT NULL AFTER `deleted`,
|
|
||||||
CHANGE `cover_id` `object2id` bigint NOT NULL AFTER `object1id`;
|
|
||||||
""");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `user`
|
|
||||||
CHANGE `id` `id` bigint NOT NULL COMMENT 'Primary key of the base' AUTO_INCREMENT FIRST,
|
|
||||||
CHANGE `createdAt` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'Create time of the object' AFTER `id`,
|
|
||||||
CHANGE `updatedAt` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'When update the object' AFTER `createdAt`,
|
|
||||||
CHANGE `deleted` `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'When delete, they are not removed, they are just set in a deleted state' AFTER `updatedAt`,
|
|
||||||
CHANGE `login` `login` varchar(128) COLLATE 'utf8mb4_0900_ai_ci' NULL AFTER `deleted`,
|
|
||||||
CHANGE `lastConnection` `lastConnection` timestamp(3) NULL AFTER `login`,
|
|
||||||
CHANGE `admin` `admin` tinyint(1) NOT NULL DEFAULT '0' AFTER `lastConnection`,
|
|
||||||
CHANGE `blocked` `blocked` tinyint(1) NOT NULL DEFAULT '0' AFTER `admin`,
|
|
||||||
CHANGE `removed` `removed` tinyint(1) NOT NULL DEFAULT '0' AFTER `blocked`;
|
|
||||||
""");
|
|
||||||
addAction("""
|
|
||||||
ALTER TABLE `userMediaAdvancement`
|
|
||||||
CHANGE `id` `id` bigint NOT NULL COMMENT 'Primary key of the base' AUTO_INCREMENT FIRST,
|
|
||||||
CHANGE `createdAt` `createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'Create time of the object' AFTER `id`,
|
|
||||||
CHANGE `updatedAt` `updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'When update the object' AFTER `createdAt`,
|
|
||||||
CHANGE `deleted` `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'When delete, they are not removed, they are just set in a deleted state' AFTER `updatedAt`,
|
|
||||||
CHANGE `userId` `userId` bigint NOT NULL COMMENT 'Foreign Key Id of the user' AFTER `deleted`,
|
|
||||||
CHANGE `mediaId` `mediaId` bigint NOT NULL COMMENT 'Id of the media' AFTER `userId`,
|
|
||||||
CHANGE `percent` `percent` float NOT NULL COMMENT 'Percent of admencement in the media' AFTER `mediaId`,
|
|
||||||
CHANGE `time` `time` int NOT NULL COMMENT 'Number of second of admencement in the media' AFTER `percent`,
|
|
||||||
CHANGE `count` `count` int NOT NULL COMMENT 'Number of time this media has been read' AFTER `time`;
|
|
||||||
""");
|
|
||||||
addAction("""
|
|
||||||
CREATE TABLE `user_link_cover` (
|
|
||||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'Primary key of the base' ,
|
|
||||||
`createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'Create time of the object' ,
|
|
||||||
`updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT 'When update the object' ,
|
|
||||||
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'When delete, they are not removed, they are just set in a deleted state' ,
|
|
||||||
`object1Id` bigint NOT NULL COMMENT 'Object reference 1' ,
|
|
||||||
`object2Id` bigint NOT NULL COMMENT 'Object reference 2' ,
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package org.kar.karideo.model;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.kar.archidata.model.Data;
|
|
||||||
import org.kar.archidata.model.GenericDataSoftDelete;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
|
||||||
|
|
||||||
import jakarta.persistence.Column;
|
|
||||||
import jakarta.persistence.Entity;
|
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.ManyToMany;
|
|
||||||
import jakarta.persistence.ManyToOne;
|
|
||||||
import jakarta.persistence.Table;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "media")
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
|
||||||
//@SQLDelete(sql = "UPDATE table_product SET deleted = true WHERE id=?")
|
|
||||||
//@Where(clause = "deleted=false")
|
|
||||||
public class Media extends GenericDataSoftDelete {
|
|
||||||
// Name of the media (this represent the title)
|
|
||||||
@Column(nullable = false, length = 0)
|
|
||||||
public String name;
|
|
||||||
// Description of the media
|
|
||||||
@Column(length = 0)
|
|
||||||
public String description;
|
|
||||||
// Foreign Key Id of the data
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Data.class)
|
|
||||||
@Column(nullable = false)
|
|
||||||
public Long dataId;
|
|
||||||
// Type of the media")
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Type.class)
|
|
||||||
public Long typeId;
|
|
||||||
// Series reference of the media
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Series.class)
|
|
||||||
public Long seriesId;
|
|
||||||
// Saison reference of the media
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Season.class)
|
|
||||||
public Long seasonId;
|
|
||||||
// Episide Id
|
|
||||||
public Integer episode;
|
|
||||||
// ")
|
|
||||||
public Integer date;
|
|
||||||
// Creation years of the media
|
|
||||||
public Integer time;
|
|
||||||
// Limitation Age of the media
|
|
||||||
public Integer ageLimit;
|
|
||||||
// List of Id of the specific covers
|
|
||||||
@ManyToMany(fetch = FetchType.LAZY, targetEntity = Data.class)
|
|
||||||
public List<Long> covers = null;
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package org.kar.karideo.model;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.kar.archidata.annotation.DataIfNotExists;
|
|
||||||
import org.kar.archidata.model.Data;
|
|
||||||
import org.kar.archidata.model.GenericDataSoftDelete;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import jakarta.persistence.Column;
|
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.ManyToMany;
|
|
||||||
import jakarta.persistence.ManyToOne;
|
|
||||||
import jakarta.persistence.Table;
|
|
||||||
|
|
||||||
@Table(name = "season")
|
|
||||||
@DataIfNotExists
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
|
||||||
public class Season extends GenericDataSoftDelete {
|
|
||||||
@Column(nullable = false, length = 0)
|
|
||||||
@Schema(description = "Name of the media (this represent the title)")
|
|
||||||
public String name;
|
|
||||||
@Column(length = 0)
|
|
||||||
@Schema(description = "Description of the media")
|
|
||||||
public String description;
|
|
||||||
@Column(nullable = false)
|
|
||||||
@Schema(description = "series parent ID")
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Series.class)
|
|
||||||
public Long parentId;
|
|
||||||
@Schema(description = "List of Id of the sopecific covers")
|
|
||||||
@ManyToMany(fetch = FetchType.LAZY, targetEntity = Data.class)
|
|
||||||
public List<Long> covers = null;
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package org.kar.karideo.model;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.kar.archidata.annotation.DataIfNotExists;
|
|
||||||
import org.kar.archidata.model.Data;
|
|
||||||
import org.kar.archidata.model.GenericDataSoftDelete;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import jakarta.persistence.Column;
|
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.ManyToMany;
|
|
||||||
import jakarta.persistence.ManyToOne;
|
|
||||||
import jakarta.persistence.Table;
|
|
||||||
|
|
||||||
@Table(name = "series")
|
|
||||||
@DataIfNotExists
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
|
||||||
public class Series extends GenericDataSoftDelete {
|
|
||||||
@Column(nullable = false, length = 0)
|
|
||||||
@Schema(description = "Name of the media (this represent the title)")
|
|
||||||
public String name;
|
|
||||||
@Column(length = 0)
|
|
||||||
@Schema(description = "Description of the media")
|
|
||||||
public String description;
|
|
||||||
@Column(nullable = false)
|
|
||||||
@Schema(description = "series parent ID")
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Type.class)
|
|
||||||
public Long parentId;
|
|
||||||
@Schema(description = "List of Id of the sopecific covers")
|
|
||||||
@ManyToMany(fetch = FetchType.LAZY, targetEntity = Data.class)
|
|
||||||
public List<Long> covers = null;
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package org.kar.karideo.model;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.kar.archidata.annotation.DataIfNotExists;
|
|
||||||
import org.kar.archidata.model.Data;
|
|
||||||
import org.kar.archidata.model.GenericDataSoftDelete;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import jakarta.persistence.Column;
|
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.ManyToMany;
|
|
||||||
import jakarta.persistence.Table;
|
|
||||||
|
|
||||||
@Table(name = "type")
|
|
||||||
@DataIfNotExists
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
|
||||||
public class Type extends GenericDataSoftDelete {
|
|
||||||
@Column(nullable = false, length = 0)
|
|
||||||
@Schema(description = "Name of the media (this represent the title)")
|
|
||||||
public String name;
|
|
||||||
@Column(length = 0)
|
|
||||||
@Schema(description = "Description of the media")
|
|
||||||
public String description;
|
|
||||||
@Schema(description = "List of Id of the sopecific covers")
|
|
||||||
@ManyToMany(fetch = FetchType.LAZY, targetEntity = Data.class)
|
|
||||||
public List<Long> covers = null;
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package org.kar.karideo.model;
|
|
||||||
|
|
||||||
import org.kar.archidata.annotation.DataIfNotExists;
|
|
||||||
import org.kar.archidata.model.GenericDataSoftDelete;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import jakarta.persistence.Column;
|
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.ManyToOne;
|
|
||||||
import jakarta.persistence.Table;
|
|
||||||
|
|
||||||
@Table(name = "userMediaAdvancement")
|
|
||||||
@DataIfNotExists
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
|
||||||
public class UserMediaAdvancement extends GenericDataSoftDelete {
|
|
||||||
@Column(nullable = false)
|
|
||||||
@Schema(description = "Foreign Key Id of the user")
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY, targetEntity = UserKarideo.class)
|
|
||||||
public long userId;
|
|
||||||
@Column(nullable = false)
|
|
||||||
@Schema(description = "Id of the media")
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Media.class)
|
|
||||||
public long mediaId;
|
|
||||||
@Column(nullable = false)
|
|
||||||
@Schema(description = "Percent of admencement in the media")
|
|
||||||
public float percent;
|
|
||||||
@Column(nullable = false)
|
|
||||||
@Schema(description = "Number of second of admencement in the media")
|
|
||||||
public int time;
|
|
||||||
@Column(nullable = false)
|
|
||||||
@Schema(description = "Number of time this media has been read")
|
|
||||||
public int count;
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package org.kar.karideo.util;
|
|
||||||
|
|
||||||
public class ConfigVariable {
|
|
||||||
public static final String BASE_NAME = "ORG_KARIDEO_";
|
|
||||||
|
|
||||||
public static String getFrontFolder() {
|
|
||||||
String out = System.getenv(BASE_NAME + "FRONT_FOLDER");
|
|
||||||
if (out == null) {
|
|
||||||
return "/application/front";
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
package test.kar.karideo;
|
package test.atriasoft.karideo;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.kar.archidata.tools.JWTWrapper;
|
import org.atriasoft.archidata.filter.PartRight;
|
||||||
|
import org.atriasoft.archidata.tools.JWTWrapper;
|
||||||
|
|
||||||
public class Common {
|
public class Common {
|
||||||
static String USER_TOKEN = JWTWrapper.createJwtTestToken(16512, "test_user_login", "KarAuth", "karideo", Map.of("karideo", Map.of("USER", Boolean.TRUE)));
|
static String USER_TOKEN = JWTWrapper.createJwtTestToken(16512, "test_user_login", "KarAuth", "karideo", Map.of("karideo", Map.of("USER", PartRight.READ)));
|
||||||
static String ADMIN_TOKEN = JWTWrapper.createJwtTestToken(16512, "test_admin_login", "KarAuth", "karideo", Map.of("karideo", Map.of("USER", Boolean.TRUE, "ADMIN", Boolean.TRUE)));
|
static String ADMIN_TOKEN = JWTWrapper.createJwtTestToken(16512, "test_admin_login", "KarAuth", "karideo", Map.of("karideo", Map.of("USER", PartRight.READ_WRITE, "ADMIN", PartRight.READ_WRITE)));
|
||||||
}
|
}
|
||||||
115
back/test/src/test/atriasoft/karideo/ConfigureDb.java
Normal file
115
back/test/src/test/atriasoft/karideo/ConfigureDb.java
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
package test.atriasoft.karideo;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.dataAccess.DBAccess;
|
||||||
|
import org.atriasoft.archidata.db.DbConfig;
|
||||||
|
import org.atriasoft.archidata.db.DbIoFactory;
|
||||||
|
import org.atriasoft.archidata.exception.DataAccessException;
|
||||||
|
import org.atriasoft.archidata.tools.ConfigBaseVariable;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.InternalServerErrorException;
|
||||||
|
|
||||||
|
public class ConfigureDb {
|
||||||
|
final static private Logger LOGGER = LoggerFactory.getLogger(ConfigureDb.class);
|
||||||
|
final static private String modeTestForced = null;// "MONGO";
|
||||||
|
public static DBAccess da = null;
|
||||||
|
|
||||||
|
public static void configure() throws IOException, InternalServerErrorException, DataAccessException {
|
||||||
|
String modeTest = System.getenv("TEST_E2E_MODE");
|
||||||
|
if (modeTest == null || modeTest.isEmpty() || "false".equalsIgnoreCase(modeTest)) {
|
||||||
|
modeTest = "SQLITE-MEMORY";
|
||||||
|
} else if ("true".equalsIgnoreCase(modeTest)) {
|
||||||
|
modeTest = "MY-SQL";
|
||||||
|
}
|
||||||
|
// override the local test:
|
||||||
|
if (modeTestForced != null) {
|
||||||
|
modeTest = modeTestForced;
|
||||||
|
}
|
||||||
|
// for local test:
|
||||||
|
ConfigBaseVariable.apiAdress = "http://127.0.0.1:12342/test/api/";
|
||||||
|
// Enable the test mode permit to access to the test token (never use it in production).
|
||||||
|
ConfigBaseVariable.testMode = "true";
|
||||||
|
if ("SQLITE-MEMORY".equalsIgnoreCase(modeTest)) {
|
||||||
|
ConfigBaseVariable.dbType = "sqlite";
|
||||||
|
ConfigBaseVariable.bdDatabase = null;
|
||||||
|
ConfigBaseVariable.dbHost = "memory";
|
||||||
|
// for test we need to connect all time the DB
|
||||||
|
ConfigBaseVariable.dbKeepConnected = "true";
|
||||||
|
} else if ("SQLITE".equalsIgnoreCase(modeTest)) {
|
||||||
|
ConfigBaseVariable.dbType = "sqlite";
|
||||||
|
ConfigBaseVariable.bdDatabase = null;
|
||||||
|
ConfigBaseVariable.dbKeepConnected = "true";
|
||||||
|
} else if ("MY-SQL".equalsIgnoreCase(modeTest)) {
|
||||||
|
ConfigBaseVariable.dbType = "mysql";
|
||||||
|
ConfigBaseVariable.bdDatabase = "test_Karideo_db";
|
||||||
|
ConfigBaseVariable.dbPort = "3906";
|
||||||
|
ConfigBaseVariable.dbUser = "root";
|
||||||
|
} else if ("MONGO".equalsIgnoreCase(modeTest)) {
|
||||||
|
ConfigBaseVariable.dbType = "mongo";
|
||||||
|
ConfigBaseVariable.bdDatabase = "test_Karideo_db";
|
||||||
|
} else {
|
||||||
|
// User local modification ...
|
||||||
|
ConfigBaseVariable.bdDatabase = "test_Karideo_db";
|
||||||
|
ConfigBaseVariable.dbPort = "3906";
|
||||||
|
ConfigBaseVariable.dbUser = "root";
|
||||||
|
}
|
||||||
|
removeDB();
|
||||||
|
// Connect the dataBase...
|
||||||
|
da = DBAccess.createInterface();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeDB() {
|
||||||
|
String modeTest = System.getenv("TEST_E2E_MODE");
|
||||||
|
if (modeTest == null || modeTest.isEmpty() || "false".equalsIgnoreCase(modeTest)) {
|
||||||
|
modeTest = "SQLITE-MEMORY";
|
||||||
|
} else if ("true".equalsIgnoreCase(modeTest)) {
|
||||||
|
modeTest = "MY-SQL";
|
||||||
|
}
|
||||||
|
// override the local test:
|
||||||
|
if (modeTestForced != null) {
|
||||||
|
modeTest = modeTestForced;
|
||||||
|
}
|
||||||
|
DbConfig config = null;
|
||||||
|
try {
|
||||||
|
config = new DbConfig();
|
||||||
|
} catch (final DataAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
LOGGER.error("Fail to clean the DB");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
config.setDbName(null);
|
||||||
|
LOGGER.info("Remove the DB and create a new one '{}'", config.getDbName());
|
||||||
|
try (final DBAccess daRoot = DBAccess.createInterface(config)) {
|
||||||
|
if ("SQLITE-MEMORY".equalsIgnoreCase(modeTest)) {
|
||||||
|
// nothing to do ...
|
||||||
|
} else if ("SQLITE".equalsIgnoreCase(modeTest)) {
|
||||||
|
daRoot.deleteDB(ConfigBaseVariable.bdDatabase);
|
||||||
|
} else if ("MY-SQL".equalsIgnoreCase(modeTest)) {
|
||||||
|
daRoot.deleteDB(ConfigBaseVariable.bdDatabase);
|
||||||
|
} else if ("MONGO".equalsIgnoreCase(modeTest)) {
|
||||||
|
daRoot.deleteDB(ConfigBaseVariable.bdDatabase);
|
||||||
|
}
|
||||||
|
daRoot.createDB(ConfigBaseVariable.bdDatabase);
|
||||||
|
} catch (final InternalServerErrorException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
LOGGER.error("Fail to clean the DB");
|
||||||
|
return;
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
LOGGER.error("Fail to clean the DB");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clear() throws IOException {
|
||||||
|
LOGGER.info("Remove the test db");
|
||||||
|
removeDB();
|
||||||
|
// The connection is by default open ==> close it at the end of test:
|
||||||
|
da.close();
|
||||||
|
DbIoFactory.closeAllForceMode();
|
||||||
|
ConfigBaseVariable.clearAllValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package test.kar.karideo;
|
package test.atriasoft.karideo;
|
||||||
|
|
||||||
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
|
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
|
||||||
import org.junit.jupiter.api.extension.ExecutionCondition;
|
import org.junit.jupiter.api.extension.ExecutionCondition;
|
||||||
48
back/test/src/test/atriasoft/karideo/TestBase.java
Normal file
48
back/test/src/test/atriasoft/karideo/TestBase.java
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package test.atriasoft.karideo;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.atriasoft.archidata.tools.ConfigBaseVariable;
|
||||||
|
import org.atriasoft.archidata.tools.RESTApi;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ExtendWith(StepwiseExtension.class)
|
||||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
public class TestBase {
|
||||||
|
private final static Logger LOGGER = LoggerFactory.getLogger(TestBase.class);
|
||||||
|
public final static String ENDPOINT_NAME = "species/";
|
||||||
|
|
||||||
|
static WebLauncherTest webInterface = null;
|
||||||
|
static RESTApi api = null;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public static void configureWebServer() throws Exception {
|
||||||
|
ConfigureDb.configure();
|
||||||
|
LOGGER.info("configure server ...");
|
||||||
|
webInterface = new WebLauncherTest();
|
||||||
|
LOGGER.info("Start REST (BEGIN)");
|
||||||
|
webInterface.process();
|
||||||
|
LOGGER.info("Start REST (DONE)");
|
||||||
|
api = new RESTApi(ConfigBaseVariable.apiAdress);
|
||||||
|
api.setToken(Common.ADMIN_TOKEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
public static void stopWebServer() throws Exception {
|
||||||
|
LOGGER.info("Kill the web server");
|
||||||
|
webInterface.stop();
|
||||||
|
webInterface = null;
|
||||||
|
ConfigureDb.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public static void TestEmpty() throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package test.kar.karideo;
|
package test.atriasoft.karideo;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
|
import org.atriasoft.archidata.exception.RESTErrorResponseException;
|
||||||
|
import org.atriasoft.archidata.tools.ConfigBaseVariable;
|
||||||
|
import org.atriasoft.archidata.tools.RESTApi;
|
||||||
|
import org.atriasoft.karideo.api.HealthCheck.HealthResult;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
@@ -10,11 +12,6 @@ import org.junit.jupiter.api.Order;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.kar.archidata.db.DBEntry;
|
|
||||||
import org.kar.archidata.exception.RESTErrorResponseExeption;
|
|
||||||
import org.kar.archidata.tools.ConfigBaseVariable;
|
|
||||||
import org.kar.archidata.tools.RESTApi;
|
|
||||||
import org.kar.karideo.api.HealthCheck.HealthResult;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -28,43 +25,36 @@ public class TestHealthCheck {
|
|||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void configureWebServer() throws Exception {
|
public static void configureWebServer() throws Exception {
|
||||||
|
ConfigureDb.configure();
|
||||||
LOGGER.info("configure server ...");
|
LOGGER.info("configure server ...");
|
||||||
webInterface = new WebLauncherTest();
|
webInterface = new WebLauncherTest();
|
||||||
LOGGER.info("Create DB");
|
|
||||||
try {
|
|
||||||
webInterface.migrateDB();
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
LOGGER.error("Detect an error: {}", ex.getMessage());
|
|
||||||
}
|
|
||||||
LOGGER.info("Start REST (BEGIN)");
|
LOGGER.info("Start REST (BEGIN)");
|
||||||
webInterface.process();
|
webInterface.process();
|
||||||
LOGGER.info("Start REST (DONE)");
|
LOGGER.info("Start REST (DONE)");
|
||||||
api = new RESTApi(ConfigBaseVariable.apiAdress);
|
api = new RESTApi(ConfigBaseVariable.apiAdress);
|
||||||
|
api.setToken(Common.ADMIN_TOKEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterAll
|
@AfterAll
|
||||||
public static void stopWebServer() throws InterruptedException, IOException {
|
public static void stopWebServer() throws Exception {
|
||||||
LOGGER.info("Kill the web server");
|
LOGGER.info("Kill the web server");
|
||||||
webInterface.stop();
|
webInterface.stop();
|
||||||
webInterface = null;
|
webInterface = null;
|
||||||
LOGGER.info("Remove the test db");
|
ConfigureDb.clear();
|
||||||
DBEntry.closeAllForceMode();
|
|
||||||
ConfigBaseVariable.clearAllValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Order(1)
|
@Order(1)
|
||||||
@Test
|
@Test
|
||||||
//@RepeatedTest(10)
|
// @RepeatedTest(10)
|
||||||
public void checkHealthCheck() throws Exception {
|
public void checkHealthCheck() throws Exception {
|
||||||
final HealthResult result = api.get(HealthResult.class, "health_check");
|
final HealthResult result = api.request("health_check").get().fetch(HealthResult.class);
|
||||||
Assertions.assertEquals(result.value(), "alive and kicking");
|
Assertions.assertEquals(result.value(), "alive and kicking");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Order(2)
|
@Order(2)
|
||||||
@Test
|
@Test
|
||||||
public void checkHealthCheckWrongAPI() throws Exception {
|
public void checkHealthCheckWrongAPI() throws Exception {
|
||||||
Assertions.assertThrows(RESTErrorResponseExeption.class, () -> api.get(HealthResult.class, "health_checks"));
|
Assertions.assertThrows(RESTErrorResponseException.class, () -> api.request("health_check_kaboom").get().fetch());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
12
back/test/src/test/atriasoft/karideo/WebLauncherTest.java
Executable file
12
back/test/src/test/atriasoft/karideo/WebLauncherTest.java
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
package test.atriasoft.karideo;
|
||||||
|
|
||||||
|
import org.atriasoft.karideo.WebLauncher;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class WebLauncherTest extends WebLauncher {
|
||||||
|
final private static Logger LOGGER = LoggerFactory.getLogger(WebLauncherTest.class);
|
||||||
|
|
||||||
|
public WebLauncherTest() {}
|
||||||
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
|
|
||||||
package test.kar.karideo;
|
|
||||||
|
|
||||||
import org.kar.archidata.tools.ConfigBaseVariable;
|
|
||||||
import org.kar.karideo.WebLauncher;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class WebLauncherTest extends WebLauncher {
|
|
||||||
final private static Logger LOGGER = LoggerFactory.getLogger(WebLauncherTest.class);
|
|
||||||
|
|
||||||
public WebLauncherTest() {
|
|
||||||
LOGGER.debug("Configure REST system");
|
|
||||||
// for local test:
|
|
||||||
ConfigBaseVariable.apiAdress = "http://127.0.0.1:12345/test/api/";
|
|
||||||
ConfigBaseVariable.testMode = "true";
|
|
||||||
//ConfigBaseVariable.dbPort = "3306";
|
|
||||||
// for the test we a in memory sqlite..
|
|
||||||
ConfigBaseVariable.dbType = "sqlite";
|
|
||||||
ConfigBaseVariable.dbHost = "memory";
|
|
||||||
// for test we need to connect all time the DB
|
|
||||||
ConfigBaseVariable.dbKeepConnected = "true";
|
|
||||||
|
|
||||||
//ConfigBaseVariable.dbHost = "localhost";
|
|
||||||
//ConfigBaseVariable.dbUser = "root";
|
|
||||||
//ConfigBaseVariable.dbPassword = "ZERTYSDGFVHSDFGHJYZSDFGSQxfgsqdfgsqdrf4564654";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
front/.env
Normal file
1
front/.env
Normal file
@@ -0,0 +1 @@
|
|||||||
|
NODE_ENV=development
|
||||||
2
front/.env.production
Normal file
2
front/.env.production
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# URL for database connection
|
||||||
|
VITE_API_BASE_URL=karideo/api/
|
||||||
27
front/.storybook/main.ts
Normal file
27
front/.storybook/main.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import type { StorybookConfig } from '@storybook/react-vite';
|
||||||
|
|
||||||
|
const config: StorybookConfig = {
|
||||||
|
framework: {
|
||||||
|
name: '@storybook/react-vite',
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
|
||||||
|
core: {
|
||||||
|
disableTelemetry: true,
|
||||||
|
builder: '@storybook/builder-vite',
|
||||||
|
},
|
||||||
|
|
||||||
|
stories: ['../src/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'],
|
||||||
|
|
||||||
|
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
|
||||||
|
|
||||||
|
staticDirs: ['../public'],
|
||||||
|
|
||||||
|
typescript: {
|
||||||
|
reactDocgen: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
docs: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
16
front/.storybook/preview-head.html
Normal file
16
front/.storybook/preview-head.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<style>
|
||||||
|
html {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs-story > :first-child {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.docs-story > * {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root #start-ui-storybook-wrapper {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
34
front/.storybook/preview.tsx
Normal file
34
front/.storybook/preview.tsx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { Box } from '@chakra-ui/react';
|
||||||
|
import { ChakraProvider } from '@chakra-ui/react';
|
||||||
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { ColorModeProvider } from '../src/components/ui/color-mode';
|
||||||
|
import { Toaster } from '../src/components/ui/toaster';
|
||||||
|
import { systemTheme } from '../src/theme/theme';
|
||||||
|
|
||||||
|
// .
|
||||||
|
const DocumentationWrapper = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<Box id="start-ui-storybook-wrapper" p="4" pb="8" flex="1">
|
||||||
|
{children}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const decorators = [
|
||||||
|
(Story, context) => (
|
||||||
|
<ColorModeProvider>
|
||||||
|
<ChakraProvider value={systemTheme}>
|
||||||
|
{/* Using MemoryRouter to avoid route clashing with Storybook */}
|
||||||
|
<MemoryRouter>
|
||||||
|
<DocumentationWrapper>
|
||||||
|
<Story {...context} />
|
||||||
|
</DocumentationWrapper>
|
||||||
|
</MemoryRouter>
|
||||||
|
<Toaster />
|
||||||
|
</ChakraProvider>
|
||||||
|
</ColorModeProvider>
|
||||||
|
),
|
||||||
|
];
|
||||||
2
front/LICENSE
Normal file
2
front/LICENSE
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Proprietary
|
||||||
|
@copyright Edouard Dupin 2024
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema" : "./node_modules/@angular/cli/lib/config/schema.json",
|
|
||||||
"version" : 1,
|
|
||||||
"newProjectRoot" : "projects",
|
|
||||||
"defaultProject" : "karideo",
|
|
||||||
"projects" : {
|
|
||||||
"karideo" : {
|
|
||||||
"root" : "",
|
|
||||||
"sourceRoot" : "src",
|
|
||||||
"projectType" : "application",
|
|
||||||
"architect" : {
|
|
||||||
"build" : {
|
|
||||||
"builder" : "@angular-devkit/build-angular:browser",
|
|
||||||
"options" : {
|
|
||||||
"outputPath" : "dist",
|
|
||||||
"index" : "src/index.html",
|
|
||||||
"main" : "src/main.ts",
|
|
||||||
"tsConfig" : "src/tsconfig.app.json",
|
|
||||||
"polyfills" : "src/polyfills.ts",
|
|
||||||
"assets" : [ "src/assets", "src/favicon.ico" ],
|
|
||||||
"styles" : [ "src/styles.less", "src/generic_page.less", "src/theme.color.blue.less", "src/theme.checkbox.less", "src/theme.modal.less" ],
|
|
||||||
"scripts" : [ ]
|
|
||||||
},
|
|
||||||
"configurations" : {
|
|
||||||
"production" : {
|
|
||||||
"optimization" : true,
|
|
||||||
"outputHashing" : "all",
|
|
||||||
"sourceMap" : false,
|
|
||||||
"namedChunks" : false,
|
|
||||||
"aot" : true,
|
|
||||||
"extractLicenses" : true,
|
|
||||||
"vendorChunk" : false,
|
|
||||||
"buildOptimizer" : true,
|
|
||||||
"fileReplacements" : [ {
|
|
||||||
"replace" : "src/environments/environment.ts",
|
|
||||||
"with" : "src/environments/environment.prod.ts"
|
|
||||||
} ]
|
|
||||||
},
|
|
||||||
"develop" : {
|
|
||||||
"optimization" : false,
|
|
||||||
"outputHashing" : "none",
|
|
||||||
"sourceMap" : true,
|
|
||||||
"namedChunks" : true,
|
|
||||||
"aot" : true,
|
|
||||||
"extractLicenses" : true,
|
|
||||||
"vendorChunk" : true,
|
|
||||||
"buildOptimizer" : false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"serve" : {
|
|
||||||
"builder" : "@angular-devkit/build-angular:dev-server",
|
|
||||||
"options" : {
|
|
||||||
"browserTarget" : "karideo:build"
|
|
||||||
},
|
|
||||||
"configurations" : {
|
|
||||||
"production" : {
|
|
||||||
"browserTarget" : "karideo:build:production"
|
|
||||||
},
|
|
||||||
"develop" : {
|
|
||||||
"browserTarget" : "karideo:build:develop"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"extract-i18n" : {
|
|
||||||
"builder" : "@angular-devkit/build-angular:extract-i18n",
|
|
||||||
"options" : {
|
|
||||||
"browserTarget" : "karideo:build"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"test" : {
|
|
||||||
"builder" : "@angular-devkit/build-angular:karma",
|
|
||||||
"options" : {
|
|
||||||
"main" : "src/test.ts",
|
|
||||||
"karmaConfig" : "./karma.conf.js",
|
|
||||||
"polyfills" : "src/polyfills.ts",
|
|
||||||
"tsConfig" : "src/tsconfig.spec.json",
|
|
||||||
"scripts" : [ ],
|
|
||||||
"styles" : [ "src/styles.less", "src/generic_page.less", "src/theme.color.blue.less", "src/theme.checkbox.less", "src/theme.modal.less" ],
|
|
||||||
"assets" : [ "src/assets", "src/favicon.ico" ]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint" : {
|
|
||||||
"builder" : "@angular-eslint/builder:lint",
|
|
||||||
"options" : {
|
|
||||||
"fix": true,
|
|
||||||
"eslintConfig": ".eslintrc.js",
|
|
||||||
"lintFilePatterns": [
|
|
||||||
"src/**/*.spec.ts",
|
|
||||||
"src/**/*.ts"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"TTTTTTlint" : {
|
|
||||||
"builder" : "@angular-devkit/build-angular:tslint",
|
|
||||||
"options" : {
|
|
||||||
"tsConfig" : [ "src/tsconfig.app.json", "src/tsconfig.spec.json" ],
|
|
||||||
"exclude" : [ "**/node_modules/**" ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"karideo-e2e" : {
|
|
||||||
"root" : "e2e",
|
|
||||||
"sourceRoot" : "e2e",
|
|
||||||
"projectType" : "application",
|
|
||||||
"architect" : {
|
|
||||||
"e2e" : {
|
|
||||||
"builder" : "@angular-devkit/build-angular:protractor",
|
|
||||||
"options" : {
|
|
||||||
"protractorConfig" : "./protractor.conf.js",
|
|
||||||
"devServerTarget" : "karideo:serve"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint" : {
|
|
||||||
"builder" : "@angular-devkit/build-angular:tslint",
|
|
||||||
"options" : {
|
|
||||||
"tsConfig" : [ "e2e/tsconfig.e2e.json" ],
|
|
||||||
"exclude" : [ "**/node_modules/**" ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"schematics" : {
|
|
||||||
"@schematics/angular:component" : {
|
|
||||||
"prefix" : "app",
|
|
||||||
"style" : "less"
|
|
||||||
},
|
|
||||||
"@schematics/angular:directive" : {
|
|
||||||
"prefix" : "app"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
10637
front/config sample.yaml
Normal file
10637
front/config sample.yaml
Normal file
File diff suppressed because it is too large
Load Diff
14
front/index.html
Normal file
14
front/index.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Karideo</title>
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
</head>
|
||||||
|
<body style="width:100vw;height:100vh;min-width:100%;min-height:100%;">
|
||||||
|
<div id="root" style="width:100%;height:100%;min-width:100%;min-height:100%;"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
9
front/knip.ts
Normal file
9
front/knip.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import type { KnipConfig } from 'knip';
|
||||||
|
|
||||||
|
const config: KnipConfig = {
|
||||||
|
// Ignoring mostly shell binaries
|
||||||
|
ignoreBinaries: ['export', 'sleep'],
|
||||||
|
ignore: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
21757
front/package-lock.json
generated
21757
front/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,41 +1,89 @@
|
|||||||
{
|
{
|
||||||
"name": "karideo",
|
"name": "karideo",
|
||||||
"version": "0.0.0",
|
|
||||||
"license": "MPL-2",
|
|
||||||
"scripts": {
|
|
||||||
"all": "npm run build && npm run test",
|
|
||||||
"ng": "ng",
|
|
||||||
"dev": "ng serve --configuration=develop --watch --port 4202",
|
|
||||||
"build": "ng build --prod",
|
|
||||||
"test": "ng test",
|
|
||||||
"lint": "ng lint",
|
|
||||||
"style": "prettier --write .",
|
|
||||||
"e2e": "ng e2e"
|
|
||||||
},
|
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "KAR web music application",
|
||||||
|
"author": {
|
||||||
|
"name": "Edouard DUPIN",
|
||||||
|
"email": "yui.heero@gmail.farm"
|
||||||
|
},
|
||||||
|
"license": "PROPRIETARY",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"update_packages": "ncu --target minor",
|
||||||
|
"upgrade_packages": "ncu --upgrade ",
|
||||||
|
"install_dependency": "pnpm install",
|
||||||
|
"test": "vitest run",
|
||||||
|
"test:watch": "vitest watch",
|
||||||
|
"build": "tsc && vite build",
|
||||||
|
"static:build": "pnpm build",
|
||||||
|
"dev": "vite",
|
||||||
|
"pretty": "prettier -w .",
|
||||||
|
"lint": "pnpm tsc --noEmit",
|
||||||
|
"storybook": "storybook dev -p 3001",
|
||||||
|
"storybook:build": "storybook build && mv ./storybook-static ./public/storybook"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{ts,tsx,js,jsx,json}": "prettier --write"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^14.2.10",
|
"react-speech-recognition": "4.0.1",
|
||||||
"@angular/cdk": "^14.2.7",
|
"regenerator-runtime": "0.14.1",
|
||||||
"@angular/common": "^14.2.10",
|
"@locator/babel-jsx": "0.4.4",
|
||||||
"@angular/compiler": "^14.2.10",
|
"@trivago/prettier-plugin-sort-imports": "5.2.2",
|
||||||
"@angular/core": "^14.2.10",
|
"@chakra-ui/cli": "3.27.1",
|
||||||
"@angular/forms": "^14.2.10",
|
"@chakra-ui/react": "3.27.1",
|
||||||
"@angular/material": "^14.2.7",
|
"@emotion/react": "11.14.0",
|
||||||
"@angular/platform-browser": "^14.2.10",
|
"allotment": "1.20.4",
|
||||||
"@angular/platform-browser-dynamic": "^14.2.10",
|
"css-mediaquery": "0.1.2",
|
||||||
"@angular/router": "^14.2.10",
|
"dayjs": "1.11.18",
|
||||||
"rxjs": "^7.5.7",
|
"history": "5.3.0",
|
||||||
"zone.js": "^0.12.0"
|
"next-themes": "^0.4.6",
|
||||||
|
"react": "19.2.0",
|
||||||
|
"react-dom": "19.2.0",
|
||||||
|
"react-error-boundary": "6.0.0",
|
||||||
|
"react-icons": "5.5.0",
|
||||||
|
"react-router-dom": "7.9.4",
|
||||||
|
"react-select": "5.10.2",
|
||||||
|
"react-use": "17.6.0",
|
||||||
|
"zod": "4.1.12",
|
||||||
|
"zustand": "5.0.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^14.2.9",
|
"@chakra-ui/styled-system": "^2.12.0",
|
||||||
"@angular-eslint/builder": "14.2.0",
|
"@playwright/test": "1.56.1",
|
||||||
"@angular-eslint/eslint-plugin": "14.2.0",
|
"@storybook/addon-links": "9.1.13",
|
||||||
"@angular-eslint/eslint-plugin-template": "14.2.0",
|
"@storybook/react-vite": "9.1.13",
|
||||||
"@angular-eslint/schematics": "14.2.0",
|
"@testing-library/jest-dom": "6.9.1",
|
||||||
"@angular-eslint/template-parser": "14.2.0",
|
"@testing-library/react": "16.3.0",
|
||||||
"@angular/cli": "^14.2.9",
|
"@testing-library/user-event": "14.6.1",
|
||||||
"@angular/compiler-cli": "^14.2.10",
|
"@trivago/prettier-plugin-sort-imports": "5.2.2",
|
||||||
"@angular/language-service": "^14.2.10"
|
"@types/jest": "30.0.0",
|
||||||
|
"@types/node": "24.8.1",
|
||||||
|
"@types/react": "19.2.2",
|
||||||
|
"@types/react-dom": "19.2.2",
|
||||||
|
"@typescript-eslint/eslint-plugin": "8.46.1",
|
||||||
|
"@typescript-eslint/parser": "8.46.1",
|
||||||
|
"@vitejs/plugin-react": "5.0.4",
|
||||||
|
"eslint": "9.38.0",
|
||||||
|
"eslint-plugin-import": "2.32.0",
|
||||||
|
"eslint-plugin-react": "7.37.5",
|
||||||
|
"eslint-plugin-react-hooks": "7.0.0",
|
||||||
|
"eslint-plugin-storybook": "9.1.13",
|
||||||
|
"jest": "30.2.0",
|
||||||
|
"jest-environment-jsdom": "30.2.0",
|
||||||
|
"knip": "5.66.0",
|
||||||
|
"lint-staged": "16.2.4",
|
||||||
|
"npm-check-updates": "^19.1.1",
|
||||||
|
"prettier": "3.6.2",
|
||||||
|
"puppeteer": "24.25.0",
|
||||||
|
"react-is": "19.2.0",
|
||||||
|
"storybook": "9.1.13",
|
||||||
|
"ts-node": "10.9.2",
|
||||||
|
"typescript": "5.9.3",
|
||||||
|
"vite": "7.1.10",
|
||||||
|
"vitest": "3.2.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
11995
front/pnpm-lock.yaml
generated
Normal file
11995
front/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
front/prettier.config.js
Normal file
16
front/prettier.config.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// Using a JS file, allowing us to add comments
|
||||||
|
module.exports = {
|
||||||
|
// This plugins line is mandatory for the plugin to work with pnpm.
|
||||||
|
// https://github.com/trivago/prettier-plugin-sort-imports/blob/61d069711008c530f5a41ca4e254781abc5de358/README.md?plain=1#L89-L96
|
||||||
|
plugins: ['@trivago/prettier-plugin-sort-imports'],
|
||||||
|
endOfLine: 'lf',
|
||||||
|
semi: true,
|
||||||
|
singleQuote: true,
|
||||||
|
tabWidth: 2,
|
||||||
|
trailingComma: 'es5',
|
||||||
|
arrowParens: 'always',
|
||||||
|
importOrder: ['^react$', '^(?!^react$|^@/|^[./]).*', '^@/(.*)$', '^[./]'],
|
||||||
|
importOrderSeparation: true,
|
||||||
|
importOrderSortSpecifiers: true,
|
||||||
|
importOrderParserPlugins: ['jsx', 'typescript'],
|
||||||
|
};
|
||||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
BIN
front/public/icons/icon-192x192.png
Normal file
BIN
front/public/icons/icon-192x192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
front/public/icons/icon-512x512.png
Normal file
BIN
front/public/icons/icon-512x512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
21
front/public/manifest.json
Normal file
21
front/public/manifest.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "Karusic",
|
||||||
|
"short_name": "Karusic",
|
||||||
|
"description": "(K)angaroo (A)nd (R)abbit m(usic) is a music streaming",
|
||||||
|
"start_url": "/karusic/",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#000000",
|
||||||
|
"theme_color": "#FFFFFF",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/karusic/icons/icon-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/karusic/icons/icon-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
20
front/src/App.tsx
Normal file
20
front/src/App.tsx
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { ErrorBoundary } from '@/errors/ErrorBoundary';
|
||||||
|
|
||||||
|
import { VideoPlayer } from './components';
|
||||||
|
import { EnvDevelopment } from './components/EnvDevelopment/EnvDevelopment';
|
||||||
|
import { AppRoutes } from './scene/AppRoutes';
|
||||||
|
import { ServiceContextProvider } from './service/ServiceContext';
|
||||||
|
|
||||||
|
export const App = () => {
|
||||||
|
return (
|
||||||
|
<ServiceContextProvider>
|
||||||
|
<EnvDevelopment />
|
||||||
|
<ErrorBoundary>
|
||||||
|
<AppRoutes />
|
||||||
|
</ErrorBoundary>
|
||||||
|
<VideoPlayer />
|
||||||
|
</ServiceContextProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
|
|
||||||
<!-- Generig global menu -->
|
|
||||||
<app-top-menu [menu]="currentMenu" (callback)="eventOnMenu($event)"></app-top-menu>
|
|
||||||
<!-- all interfaced pages -->
|
|
||||||
<div class="main-content" *ngIf="autoConnectedDone">
|
|
||||||
<router-outlet ></router-outlet>
|
|
||||||
</div>
|
|
||||||
<div class="main-content" *ngIf="!autoConnectedDone">
|
|
||||||
<div class="generic-page">
|
|
||||||
<div class="fill-all colomn_mutiple">
|
|
||||||
<b style="color:red;">Auto-connection in progress</b>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
|
|
||||||
<div class="imgContainer-small">
|
|
||||||
<div *ngIf="covers">
|
|
||||||
<!--<data-image id="{{cover}}"></data-image>-->
|
|
||||||
<img src="{{covers[0]}}"/>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!covers" class="noImage">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="season-small">
|
|
||||||
Season {{numberSeason}}
|
|
||||||
</div>
|
|
||||||
<div class="description-small" *ngIf="count > 1">
|
|
||||||
{{count}} Episodes
|
|
||||||
</div>
|
|
||||||
<div class="description-small" *ngIf="count == 1">
|
|
||||||
{{count}} Episode
|
|
||||||
</div>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<div>
|
|
||||||
<div class="count-base">
|
|
||||||
<div class="count" *ngIf="countvideo">
|
|
||||||
{{countvideo}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="imgContainer-small">
|
|
||||||
<div *ngIf="covers">
|
|
||||||
<!--<data-image id="{{cover}}"></data-image>-->
|
|
||||||
<img src="{{covers[0]}}"/>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!covers" class="noImage">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="title-small">
|
|
||||||
{{name}}
|
|
||||||
</div>
|
|
||||||
<!--
|
|
||||||
<div class="description-small" *ngIf="description">
|
|
||||||
{{description}}
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
</div>
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
<div>
|
|
||||||
<div class="count-base">
|
|
||||||
<span class="count" *ngIf="countvideo">
|
|
||||||
{{countvideo}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="imgContainer-small">
|
|
||||||
<div *ngIf="covers">
|
|
||||||
<img src="{{covers[0]}}" class="miniature-small"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="title-small">
|
|
||||||
{{name}}
|
|
||||||
</div>
|
|
||||||
<div class="description-small" *ngIf="description">
|
|
||||||
{{description}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
<div>
|
|
||||||
<div class="count-base">
|
|
||||||
<span class="views" *ngIf="advancement">
|
|
||||||
{{advancement.count}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="videoImgContainer">
|
|
||||||
<div *ngIf="covers">
|
|
||||||
<!--<data-image id="{{cover}}"></data-image>-->
|
|
||||||
<img src="{{covers[0]}}" />
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!covers" class="noImage">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="view-progess" [ngStyle]="updateAdvancement()"></div>
|
|
||||||
<div class="title-small" *ngIf="data">
|
|
||||||
{{episodeDisplay}} {{name}}
|
|
||||||
</div>
|
|
||||||
<div class="title-small" *ngIf="!data">
|
|
||||||
Error media: {{element?.id}}
|
|
||||||
</div>
|
|
||||||
<!--
|
|
||||||
<div class="description-small" *ngIf="description">
|
|
||||||
{{description}}
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
</div>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import { Media, isMedia } from "./media";
|
|
||||||
|
|
||||||
export {
|
|
||||||
Media, isMedia,
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import { isNumberFinite, isString, isOptionalOf } from "common/utils";
|
|
||||||
import { isNodeData, NodeData } from "common/model/node";
|
|
||||||
|
|
||||||
|
|
||||||
export interface Media extends NodeData {
|
|
||||||
dataId?: number;
|
|
||||||
typeId?: number;
|
|
||||||
seriesId?: number;
|
|
||||||
seasonId?: number;
|
|
||||||
episode?: number;
|
|
||||||
date?: number;
|
|
||||||
time?: number;
|
|
||||||
ageLimit?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function isMedia(data: any): data is Media {
|
|
||||||
if (!isNodeData(data) as any) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.dataId, isNumberFinite)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.typeId, isNumberFinite)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.seriesId, isNumberFinite)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.seasonId, isNumberFinite)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.episode, isNumberFinite)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.date, isNumberFinite)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.time, isNumberFinite)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isOptionalOf(data.ageLimit, isNumberFinite)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
import { isNumberFinite, isString, isOptionalOf, isNumber } from "common/utils";
|
|
||||||
import { isNodeData, NodeData } from "common/model/node";
|
|
||||||
|
|
||||||
|
|
||||||
export interface UserMediaAdvancement {
|
|
||||||
id: number;
|
|
||||||
|
|
||||||
// Id of the media
|
|
||||||
mediaId?: number;
|
|
||||||
// Percent of advancement in the media
|
|
||||||
percent?: number;
|
|
||||||
// "Number of second of advancement in the media
|
|
||||||
time?: number;
|
|
||||||
// Number of time this media has been read
|
|
||||||
count?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function isUserMediaAdvancement(data: any): data is UserMediaAdvancement {
|
|
||||||
if (!isNumberFinite(data.id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isNumberFinite(data.mediaId)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isNumber(data.percent)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isNumberFinite(data.time)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!isNumberFinite(data.count)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<div class="generic-page">
|
|
||||||
<div class="title">
|
|
||||||
Karideo
|
|
||||||
</div>
|
|
||||||
<div class="fill-all colomn_mutiple">
|
|
||||||
<div *ngFor="let data of dataList" class="item-home" (click)="onSelectType($event, data.id)" (auxclick)="onSelectType($event, data.id)">
|
|
||||||
<app-element-type [element]="data"></app-element-type>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
<div class="main-reduce edit-page">
|
|
||||||
<div class="title">
|
|
||||||
Edit season
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="itemIsRemoved">
|
|
||||||
<div class="message-big">
|
|
||||||
<br/><br/><br/>
|
|
||||||
The season has been removed
|
|
||||||
<br/><br/><br/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="itemIsNotFound">
|
|
||||||
<div class="message-big">
|
|
||||||
<br/><br/><br/>
|
|
||||||
The season does not exist
|
|
||||||
<br/><br/><br/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="itemIsLoading">
|
|
||||||
<div class="message-big">
|
|
||||||
<br/><br/><br/>
|
|
||||||
Loading ...<br/>
|
|
||||||
Please wait.
|
|
||||||
<br/><br/><br/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Number:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<input type="number"
|
|
||||||
placeholder="Id of the season"
|
|
||||||
[value]="numberVal"
|
|
||||||
(input)="onNumber($event.target.value)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Description:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<input type="text"
|
|
||||||
placeholder="Description of the Media"
|
|
||||||
[value]="description"
|
|
||||||
(input)="onDescription($event.target.value)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="send_value">
|
|
||||||
<button class="button fill-x color-button-validate color-shadow-black" (click)="sendValues()" type="submit"><i class="material-icons">save_alt</i> Save</button>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
<!-- ------------------------- Cover section --------------------------------- -->
|
|
||||||
<div class="title" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
Covers
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
<div class="hide-element">
|
|
||||||
<input type="file"
|
|
||||||
#fileInput
|
|
||||||
(change)="onChangeCover($event.target)"
|
|
||||||
placeholder="Select a cover file"
|
|
||||||
accept=".png,.jpg,.jpeg,.webp"/>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="input">
|
|
||||||
<div class="cover" *ngFor="let element of coversDisplay">
|
|
||||||
<div class="cover-image">
|
|
||||||
<img src="{{element.url}}"/>
|
|
||||||
</div>
|
|
||||||
<div class="cover-button">
|
|
||||||
<button (click)="removeCover(element.id)">
|
|
||||||
<i class="material-icons button-remove">highlight_off</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="cover">
|
|
||||||
<div class="cover-no-image">
|
|
||||||
</div>
|
|
||||||
<div class="cover-button">
|
|
||||||
<button (click)="fileInput.click()">
|
|
||||||
<i class="material-icons button-add">add_circle_outline</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
<!-- ------------------------- ADMIN section --------------------------------- -->
|
|
||||||
<div class="title" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
Administration
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
<i class="material-icons">data_usage</i> ID:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
{{idSeason}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Videos:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
{{videoCount}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
<i class="material-icons">delete_forever</i> Trash:
|
|
||||||
</div>
|
|
||||||
<div class="input" *ngIf="(videoCount == '0')">
|
|
||||||
<button class="button color-button-cancel color-shadow-black" (click)="removeItem()" type="submit">
|
|
||||||
<i class="material-icons">delete</i> Remove season
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="input" *ngIf="(videoCount != '0')">
|
|
||||||
<i class="material-icons">new_releases</i> Can not remove season, video depending on it
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<upload-progress [mediaTitle]="upload.labelMediaTitle"
|
|
||||||
[mediaUploaded]="upload.mediaSendSize"
|
|
||||||
[mediaSize]="upload.mediaSize"
|
|
||||||
[result]="upload.result"
|
|
||||||
[error]="upload.error"></upload-progress>
|
|
||||||
<delete-confirm
|
|
||||||
[comment]="confirmDeleteComment"
|
|
||||||
[imageUrl]=confirmDeleteImageUrl
|
|
||||||
(callback)="deleteConfirmed()"></delete-confirm>
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
<div class="generic-page">
|
|
||||||
<div class="fill-title colomn_mutiple">
|
|
||||||
<div class="cover-area">
|
|
||||||
<div class="cover" *ngIf="cover != null" >
|
|
||||||
<img src="{{cover}}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div [className]="cover != null ? 'description-area description-area-cover' : 'description-area description-area-no-cover'">
|
|
||||||
<div *ngIf="seriesName" class="title">
|
|
||||||
{{seriesName}}
|
|
||||||
</div>
|
|
||||||
<div class="sub-title-main">
|
|
||||||
Season {{name}}
|
|
||||||
</div>
|
|
||||||
<div class="description" *ngIf="description">
|
|
||||||
{{description}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-content colomn_mutiple">
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="title" *ngIf="videos.length > 1">Videos:</div>
|
|
||||||
<div class="title" *ngIf="videos.length == 1">Video:</div>
|
|
||||||
<div *ngFor="let data of videos" class="item item-video" (click)="onSelectVideo($event, data.id)" (auxclick)="onSelectVideo($event, data.id)">
|
|
||||||
<app-element-video [element]="data"></app-element-video>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
<div class="main-reduce edit-page">
|
|
||||||
<div class="title">
|
|
||||||
Edit series
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="itemIsRemoved">
|
|
||||||
<div class="message-big">
|
|
||||||
<br/><br/><br/>
|
|
||||||
The series has been removed
|
|
||||||
<br/><br/><br/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="itemIsNotFound">
|
|
||||||
<div class="message-big">
|
|
||||||
<br/><br/><br/>
|
|
||||||
The series does not exist
|
|
||||||
<br/><br/><br/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="itemIsLoading">
|
|
||||||
<div class="message-big">
|
|
||||||
<br/><br/><br/>
|
|
||||||
Loading ...<br/>
|
|
||||||
Please wait.
|
|
||||||
<br/><br/><br/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Type:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<select [ngModel]="typeId"
|
|
||||||
(ngModelChange)="onChangeType($event)">
|
|
||||||
<option *ngFor="let element of listType" [ngValue]="element.value">{{element.label}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Name:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<input type="text"
|
|
||||||
placeholder="Name of the Series"
|
|
||||||
[value]="name"
|
|
||||||
(input)="onName($event.target.value)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Description:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<input type="text"
|
|
||||||
placeholder="Description of the Media"
|
|
||||||
[value]="description"
|
|
||||||
(input)="onDescription($event.target.value)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="send_value">
|
|
||||||
<button class="button fill-x color-button-validate color-shadow-black" (click)="sendValues()" type="submit"><i class="material-icons">save_alt</i> Save</button>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
<!-- ------------------------- Cover section --------------------------------- -->
|
|
||||||
<div class="title" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
Covers
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
<div class="hide-element">
|
|
||||||
<input type="file"
|
|
||||||
#fileInput
|
|
||||||
(change)="onChangeCover($event.target)"
|
|
||||||
placeholder="Select a cover file"
|
|
||||||
accept=".png,.jpg,.jpeg,.webp"/>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="input">
|
|
||||||
<div class="cover" *ngFor="let element of coversDisplay">
|
|
||||||
<div class="cover-image">
|
|
||||||
<img src="{{element.url}}"/>
|
|
||||||
</div>
|
|
||||||
<div class="cover-button">
|
|
||||||
<button (click)="removeCover(element.id)">
|
|
||||||
<i class="material-icons button-remove">highlight_off</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="cover">
|
|
||||||
<div class="cover-no-image">
|
|
||||||
</div>
|
|
||||||
<div class="cover-button">
|
|
||||||
<button (click)="fileInput.click()">
|
|
||||||
<i class="material-icons button-add">add_circle_outline</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
<!-- ------------------------- ADMIN section --------------------------------- -->
|
|
||||||
<div class="title" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
Administration
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
<i class="material-icons">data_usage</i> ID:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
{{idSeries}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Seasons:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
{{seasonsCount}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Videos:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
{{videoCount}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
<i class="material-icons">delete_forever</i> Trash:
|
|
||||||
</div>
|
|
||||||
<div class="input" *ngIf="(videoCount == '0' && seasonsCount == '0')">
|
|
||||||
<button class="button color-button-cancel color-shadow-black" (click)="removeItem()" type="submit">
|
|
||||||
<i class="material-icons">delete</i> Remove Series
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="input" *ngIf="(videoCount != '0' || seasonsCount != '0')">
|
|
||||||
<i class="material-icons">new_releases</i> Can not remove season or video depending on it
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<upload-progress [mediaTitle]="upload.labelMediaTitle"
|
|
||||||
[mediaUploaded]="upload.mediaSendSize"
|
|
||||||
[mediaSize]="upload.mediaSize"
|
|
||||||
[result]="upload.result"
|
|
||||||
[error]="upload.error"></upload-progress>
|
|
||||||
<delete-confirm
|
|
||||||
[comment]="confirmDeleteComment"
|
|
||||||
[imageUrl]=confirmDeleteImageUrl
|
|
||||||
(callback)="deleteConfirmed()"></delete-confirm>
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
<div class="generic-page">
|
|
||||||
<div class="fill-title colomn_mutiple">
|
|
||||||
<div class="cover-area">
|
|
||||||
<div class="cover" *ngIf="cover != null" >
|
|
||||||
<img src="{{cover}}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div [className]="cover != null ? 'description-area description-area-cover' : 'description-area description-area-no-cover'">
|
|
||||||
<div class="title">
|
|
||||||
{{name}}
|
|
||||||
</div>
|
|
||||||
<div class="description" *ngIf="description">
|
|
||||||
{{description}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-content colomn_mutiple" *ngIf="seasons.length != 0">
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="title" *ngIf="seasons.length > 1">Seasons:</div>
|
|
||||||
<div class="title" *ngIf="seasons.length == 1">Season:</div>
|
|
||||||
<div *ngFor="let data of seasons" class="item-list" (click)="onSelectSeason($event, data.id)" (auxclick)="onSelectSeason($event, data.id)">
|
|
||||||
<app-element-season [element]="data"></app-element-season>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-content colomn_mutiple" *ngIf="videos.length != 0">
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="title" *ngIf="videos.length > 1">Videos:</div>
|
|
||||||
<div class="title" *ngIf="videos.length == 1">Video:</div>
|
|
||||||
<div *ngFor="let data of videos" class="item item-video" (click)="onSelectVideo($event, data.id)" (auxclick)="onSelectVideo($event, data.id)">
|
|
||||||
<app-element-video [element]="data"></app-element-video>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<div class="generic-page">
|
|
||||||
<div class="fill-title colomn_mutiple">
|
|
||||||
<div class="cover-area">
|
|
||||||
<div class="cover" *ngIf="cover != null" >
|
|
||||||
<img src="{{cover}}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div [className]="cover != null ? 'description-area description-area-cover' : 'description-area description-area-no-cover'">
|
|
||||||
<div class="title">
|
|
||||||
{{name}}
|
|
||||||
</div>
|
|
||||||
<div class="description" *ngIf="description">
|
|
||||||
{{description}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-content colomn_mutiple">
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div *ngFor="let data of series" class="item" (click)="onSelectSeries($event, data.id)" (auxclick)="onSelectSeries($event, data.id)">
|
|
||||||
<app-element-series [element]="data"></app-element-series>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-content colomn_mutiple">
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div *ngFor="let data of videos" class="item item-video" (click)="onSelectVideo($event, data.id)" (auxclick)="onSelectVideo($event, data.id)">
|
|
||||||
<app-element-video [element]="data"></app-element-video>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
<div class="generic-page">
|
|
||||||
<div class="title">
|
|
||||||
Upload Media
|
|
||||||
</div>
|
|
||||||
<div class="clear"><br/></div>
|
|
||||||
<div class="request_raw_table">
|
|
||||||
<table>
|
|
||||||
<colgroup>
|
|
||||||
<col style="width:10%">
|
|
||||||
<col style="width:80%">
|
|
||||||
</colgroup>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td class="left-colomn">format:</td>
|
|
||||||
<td class="right-colomn">
|
|
||||||
The format of the media permit to automatic find meta-data:<br/>
|
|
||||||
Univers:Series name-sXX-eXX-my name of my media.mkv<br/>
|
|
||||||
<b>example:</b> Stargate:SG1-s55-e22-Asgard.mkv <br/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="left-colomn">Media:</td>
|
|
||||||
<td class="right-colomn">
|
|
||||||
<input type="file"
|
|
||||||
(change)="onChangeFile($event.target)"
|
|
||||||
placeholder="Select a media file"
|
|
||||||
accept=".mkv,.webm"
|
|
||||||
width="90%"
|
|
||||||
multiple/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="this.parsedElement.length !== 0" class="title">
|
|
||||||
Meta-data:
|
|
||||||
</div>
|
|
||||||
<div class="clear"><br/></div>
|
|
||||||
<div *ngIf="this.parsedElement.length !== 0" class="fill-all">
|
|
||||||
<div class="request_raw_table">
|
|
||||||
<table>
|
|
||||||
<colgroup>
|
|
||||||
<col style="width:10%">
|
|
||||||
<col style="width:70%">
|
|
||||||
<col style="width:10%">
|
|
||||||
</colgroup>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td class="left-colomn">Type:</td>
|
|
||||||
<td class="right-colomn">
|
|
||||||
<select [ngModel]="typeId"
|
|
||||||
(ngModelChange)="onChangeType($event)"
|
|
||||||
[class.error]="typeId === undefined">
|
|
||||||
<option *ngFor="let element of listType" [ngValue]="element.value">{{element.label}}</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="left-colomn">Series:</td>
|
|
||||||
<td class="right-colomn">
|
|
||||||
<input type="text"
|
|
||||||
placeholder="Series of the Media"
|
|
||||||
[value]="globalSeries"
|
|
||||||
(input)="onSeries($event.target.value)"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="left-colomn"></td>
|
|
||||||
<td class="right-colomn">
|
|
||||||
<select [ngModel]="seriesId"
|
|
||||||
(ngModelChange)="onChangeSeries($event)">
|
|
||||||
<option *ngFor="let element of listSeries" [ngValue]="element.value">{{element.label}}</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
<td class="tool-colomn">
|
|
||||||
<!--
|
|
||||||
<button class="button color-button-normal color-shadow-black" (click)="newSeries()" type="submit">
|
|
||||||
<i class="material-icons">add_circle_outline</i>
|
|
||||||
</button>
|
|
||||||
-->
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="left-colomn">Season:</td>
|
|
||||||
<td class="right-colomn">
|
|
||||||
<input type="number"
|
|
||||||
pattern="[0-9]{0-4}"
|
|
||||||
placeholder="season of the Media"
|
|
||||||
[value]="globalSeason"
|
|
||||||
(input)="onSeason($event.target.value)"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="request_raw_table">
|
|
||||||
<table>
|
|
||||||
<colgroup>
|
|
||||||
<col style="width:10%">
|
|
||||||
<col style="width:70%">
|
|
||||||
<col style="width:10%">
|
|
||||||
</colgroup>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Episode ID:</th>
|
|
||||||
<th>Episode Title:</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr *ngFor="let data of this.parsedElement">
|
|
||||||
<td class="left-colomn">
|
|
||||||
<input type="number"
|
|
||||||
pattern="[0-9]{0-4}"
|
|
||||||
placeholder="e?"
|
|
||||||
[value]="data.episode"
|
|
||||||
(input)="onEpisode(data, $event.target.value)"
|
|
||||||
[class.error]="data.episodeDetected === true"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
<td class="right-colomn" >
|
|
||||||
<input type="text"
|
|
||||||
placeholder="Name of the Media"
|
|
||||||
[value]="data.title"
|
|
||||||
(input)="onTitle(data, $event.target.value)"
|
|
||||||
[class.error]="data.title === ''"
|
|
||||||
/>
|
|
||||||
<span *ngIf="data.nameDetected === true" class="error">
|
|
||||||
^^^This title already exist !!!
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td class="tool-colomn" >
|
|
||||||
<button class="button color-button-cancel color-shadow-black"
|
|
||||||
(click)="removeElmentFromList(data, $event.target.value)"
|
|
||||||
type="submit"
|
|
||||||
alt="Delete">
|
|
||||||
<i class="material-icons">delete</i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="send_value">
|
|
||||||
<button class="button fill-x color-button-validate color-shadow-black"
|
|
||||||
[disabled]="!needSend"
|
|
||||||
(click)="sendFile()"
|
|
||||||
type="submit">
|
|
||||||
<i class="material-icons">cloud_upload</i> Upload
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="request_raw_table" *ngIf="this.listFileInBdd !== undefined">
|
|
||||||
<table>
|
|
||||||
<colgroup>
|
|
||||||
<col style="width:10%">
|
|
||||||
<col style="width:70%">
|
|
||||||
<col style="width:10%">
|
|
||||||
</colgroup>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Episode ID:</th>
|
|
||||||
<th>Episode Title:</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr *ngFor="let data of this.listFileInBdd">
|
|
||||||
<td class="left-colomn" [class.error]="data.episodeDetected === true">{{data.episode}}</td>
|
|
||||||
<td class="right-colomn" [class.error]="data.nameDetected === true">{{data.name}}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="this.parsedElement.length !== 0" class="fill-all">
|
|
||||||
<div class="request_raw_table">
|
|
||||||
<table>
|
|
||||||
<colgroup>
|
|
||||||
<col style="width:10%">
|
|
||||||
<col style="width:80%">
|
|
||||||
</colgroup>
|
|
||||||
<tbody>
|
|
||||||
<!-- no need
|
|
||||||
<tr *ngFor="let data of this.parsedElement">
|
|
||||||
<td class="left-colomn">Keep:</td>
|
|
||||||
<td class="right-colomn">
|
|
||||||
{{data.file.name}}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
-->
|
|
||||||
<tr *ngFor="let data of this.parsedFailedElement">
|
|
||||||
<td class="left-colomn">Rejected:</td>
|
|
||||||
<td class="right-colomn">
|
|
||||||
{{data.file.name}}<br/> ==> {{data.reason}}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<upload-progress [mediaTitle]="upload.labelMediaTitle"
|
|
||||||
[mediaUploaded]="upload.mediaSendSize"
|
|
||||||
[mediaSize]="upload.mediaSize"
|
|
||||||
[result]="upload.result"
|
|
||||||
[error]="upload.error"></upload-progress>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
TODO: add a pop-in with:
|
|
||||||
- upload done
|
|
||||||
- upload error
|
|
||||||
-->
|
|
||||||
@@ -1,230 +0,0 @@
|
|||||||
<div class="main-reduce edit-page">
|
|
||||||
<div class="title">
|
|
||||||
Edit Media
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="itemIsRemoved">
|
|
||||||
<div class="message-big">
|
|
||||||
<br/><br/><br/>
|
|
||||||
The media has been removed
|
|
||||||
<br/><br/><br/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="itemIsNotFound">
|
|
||||||
<div class="message-big">
|
|
||||||
<br/><br/><br/>
|
|
||||||
The media does not exist
|
|
||||||
<br/><br/><br/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="itemIsLoading">
|
|
||||||
<div class="message-big">
|
|
||||||
<br/><br/><br/>
|
|
||||||
Loading ...<br/>
|
|
||||||
Please wait.
|
|
||||||
<br/><br/><br/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fill-all" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Title:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<input type="text"
|
|
||||||
placeholder="Name of the Media"
|
|
||||||
[value]="data.name"
|
|
||||||
(input)="onName($event.target.value)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw2">
|
|
||||||
<div class="label">
|
|
||||||
<i class="material-icons">description</i> Description:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<textarea (input)="onDescription($event.target.value)" placeholder="Description of the Media" rows=6>{{data.description}}</textarea>
|
|
||||||
<!--<input type="text"
|
|
||||||
placeholder="Description of the Media"
|
|
||||||
[value]="data.description"
|
|
||||||
(input)="onDescription($event.target.value)"/>-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
<i class="material-icons">date_range</i> Date:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<input type="number"
|
|
||||||
pattern="[0-9]{0-4}"
|
|
||||||
placeholder="2112"
|
|
||||||
[value]="data.time"
|
|
||||||
(input)="onDate($event.target)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Type:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<select [ngModel]="data.typeId"
|
|
||||||
(ngModelChange)="onChangeType($event)">
|
|
||||||
<option *ngFor="let element of listType" [ngValue]="element.value">{{element.label}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="input_add">
|
|
||||||
<button class="button color-button-normal color-shadow-black" (click)="newType()" type="submit">
|
|
||||||
<i class="material-icons">add_circle_outline</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Series:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<select [ngModel]="data.seriesId"
|
|
||||||
(ngModelChange)="onChangeSeries($event)">
|
|
||||||
<option *ngFor="let element of listSeries" [ngValue]="element.value">{{element.label}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="input_add">
|
|
||||||
<button class="button color-button-normal color-shadow-black" (click)="newSeries()" type="submit">
|
|
||||||
<i class="material-icons">add_circle_outline</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Season:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<select [ngModel]="data.seasonId"
|
|
||||||
(ngModelChange)="onChangeSeason($event)">
|
|
||||||
<option *ngFor="let element of listSeason" [ngValue]="element.value">{{element.label}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="input_add">
|
|
||||||
<button class="button color-button-normal color-shadow-black" (click)="newSeason()" type="submit">
|
|
||||||
<i class="material-icons">add_circle_outline</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
Episode:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<input type="number"
|
|
||||||
pattern="[0-9]{0-4}"
|
|
||||||
placeholder="5"
|
|
||||||
[value]="data.episode"
|
|
||||||
(input)="onEpisode($event.target)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="send_value">
|
|
||||||
<button class="button fill-x color-button-validate color-shadow-black" [disabled]="!needSend" (click)="sendValues()" type="submit"><i class="material-icons">save_alt</i> Save</button>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
<!-- ------------------------- Cover section --------------------------------- -->
|
|
||||||
<div class="title" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
Covers
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
<div class="hide-element">
|
|
||||||
<input type="file"
|
|
||||||
#fileInput
|
|
||||||
(change)="onChangeCover($event.target)"
|
|
||||||
placeholder="Select a cover file"
|
|
||||||
accept=".png,.jpg,.jpeg,.webp"/>
|
|
||||||
</div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="input">
|
|
||||||
<div class="cover" *ngFor="let element of coversDisplay">
|
|
||||||
<div class="cover-image">
|
|
||||||
<img src="{{element.url}}"/>
|
|
||||||
</div>
|
|
||||||
<div class="cover-button">
|
|
||||||
<button (click)="removeCover(element.id)">
|
|
||||||
<i class="material-icons button-remove">highlight_off</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="cover">
|
|
||||||
<div class="cover-no-image">
|
|
||||||
</div>
|
|
||||||
<div class="cover-button">
|
|
||||||
<button (click)="fileInput.click()">
|
|
||||||
<i class="material-icons button-add">add_circle_outline</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
<!-- ------------------------- ADMIN section --------------------------------- -->
|
|
||||||
<div class="title" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
Administration
|
|
||||||
</div>
|
|
||||||
<div class="fill-all" *ngIf="!itemIsRemoved && !itemIsNotFound && !itemIsLoading">
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
<i class="material-icons">data_usage</i> ID:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
{{data.dataId}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
<div class="request_raw">
|
|
||||||
<div class="label">
|
|
||||||
<i class="material-icons">delete_forever</i> Trash:
|
|
||||||
</div>
|
|
||||||
<div class="input">
|
|
||||||
<button class="button color-button-cancel color-shadow-black" (click)="removeItem()" type="submit">
|
|
||||||
<i class="material-icons">delete</i> Remove Media
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<create-type ></create-type>
|
|
||||||
|
|
||||||
<upload-progress [mediaTitle]="upload.labelMediaTitle"
|
|
||||||
[mediaUploaded]="upload.mediaSendSize"
|
|
||||||
[mediaSize]="upload.mediaSize"
|
|
||||||
[result]="upload.result"
|
|
||||||
[error]="upload.error"></upload-progress>
|
|
||||||
|
|
||||||
<delete-confirm
|
|
||||||
[comment]="confirmDeleteComment"
|
|
||||||
[imageUrl]=confirmDeleteImageUrl
|
|
||||||
(callback)="deleteConfirmed()"></delete-confirm>
|
|
||||||
|
|
||||||
<app-popin id="popin-new-season"
|
|
||||||
popTitle="Create a new season"
|
|
||||||
closeTopRight="true"
|
|
||||||
closeTitle="Cancel"
|
|
||||||
validateTitle="Create"
|
|
||||||
(callback)="eventPopUpSeason($event[0])">
|
|
||||||
<p>
|
|
||||||
Name: <!-- <input type="text" [(ngModel)]="bodyText" /> -->
|
|
||||||
</p>
|
|
||||||
</app-popin>
|
|
||||||
|
|
||||||
<app-popin id="popin-new-series"
|
|
||||||
popSize="small"
|
|
||||||
popTitle="Create a new series"
|
|
||||||
closeTopRight="true"
|
|
||||||
closeTitle="Cancel"
|
|
||||||
validateTitle="Create"
|
|
||||||
(callback)="eventPopUpSeries($event[0])">
|
|
||||||
<p>
|
|
||||||
Name: <!-- <input type="text" [(ngModel)]="bodyText" /> -->
|
|
||||||
</p>
|
|
||||||
</app-popin>
|
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user