rajah 10 mesiacov pred
rodič
commit
b0f19b2c81

BIN
.gradle/8.11.1/checksums/checksums.lock


BIN
.gradle/8.11.1/executionHistory/executionHistory.bin


BIN
.gradle/8.11.1/executionHistory/executionHistory.lock


BIN
.gradle/8.11.1/fileHashes/fileHashes.bin


BIN
.gradle/8.11.1/fileHashes/fileHashes.lock


BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock


BIN
.gradle/file-system.probe


+ 1 - 0
build.gradle

@@ -34,6 +34,7 @@ dependencies {
 	
 	implementation 'org.apache.pdfbox:pdfbox:3.0.4' 
 	implementation 'com.github.vandeseer:easytable:1.0.2'
+	implementation 'org.apache.tika:tika-core:3.1.0'
 	
 	runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6'
   runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'

+ 3 - 0
src/main/java/fr/triplea/demovote/dao/PresentationRepository.java

@@ -16,6 +16,9 @@ public interface PresentationRepository extends JpaRepository<Presentation, Inte
   
   @NativeQuery("SELECT DISTINCT p.* FROM vote.presentations AS p WHERE p.numero_categorie = :numero_cat AND p.numero_production = :numero_prod ")
   Presentation findByCategorieAndProduction(@Param("numero_cat") int numeroCategorie, @Param("numero_prod") int numeroProduction);
+
+  @NativeQuery("SELECT DISTINCT p.* FROM vote.presentations AS p WHERE p.numero_production = :numero_prod ")
+  Presentation findByProduction(@Param("numero_prod") int numeroProduction);
   
   @NativeQuery("SELECT DISTINCT p.* FROM vote.presentations AS p WHERE p.numero_categorie = :numero ORDER BY p.numero_ordre ASC ")
   List<Presentation> findByCategorie(@Param("numero") int numeroCategorie);

+ 11 - 0
src/main/java/fr/triplea/demovote/dto/PresentationFile.java

@@ -0,0 +1,11 @@
+package fr.triplea.demovote.dto;
+
+public record PresentationFile
+(
+  int numeroProduction,
+  int etatMedia,
+  String mediaMime,
+  String mediaData,
+  String mediaName
+) 
+{ }

+ 27 - 4
src/main/java/fr/triplea/demovote/model/Presentation.java

@@ -1,8 +1,13 @@
 package fr.triplea.demovote.model;
 
+import java.io.ByteArrayInputStream;
 import java.sql.Types;
 import java.util.Base64;
 
+import org.apache.tika.config.TikaConfig;
+import org.apache.tika.io.TikaInputStream;
+import org.apache.tika.metadata.Metadata;
+import org.apache.tika.metadata.TikaCoreProperties;
 import org.hibernate.annotations.JdbcTypeCode;
 import org.springframework.util.StringUtils;
 
@@ -42,7 +47,7 @@ public class Presentation
   private Integer etatMedia = 0; // 0 = non traité, 1 = média en place pour présentation, 2 = média externe (trop gros ou exécutable à lancer sur machine spécifique)
 
   @Column(name="media_mime", length = 128)
-  private String mediaMime = "application/octet-stream";
+  private String mediaMime;
 
   @Lob @JdbcTypeCode(Types.BINARY)
   @Column(name="media_data")
@@ -74,19 +79,37 @@ public class Presentation
   public void setMediaMime(String str) { if (str != null) { this.mediaMime = StringUtils.truncate(str, 128); } }
   public String getMediaMime() { return this.mediaMime; }
 
-  public void setMediaData(String a) 
+  @Transient
+  public void setMediaData(String a, String n) 
   { 
+    if (a == null) { this.mediaData = null; this.mediaMime = null; return; }
+    
     if (a.startsWith("data:") && a.contains(",")) { a = a.split(",")[1]; } 
   
     try { this.mediaData = Base64.getDecoder().decode(a); } catch(Exception e) { this.mediaData = null; }
+    
+    try 
+    {
+      byte[] debut = new byte[Math.min(this.mediaData.length, 32000)];
+
+      ByteArrayInputStream bais = new ByteArrayInputStream(debut);
+
+      TikaConfig tika = new TikaConfig();
+      
+      Metadata meta = new Metadata();
+      
+      meta.set(TikaCoreProperties.RESOURCE_NAME_KEY, n);
+
+      this.mediaMime = tika.getDetector().detect(TikaInputStream.get(bais), meta).toString();
+    } 
+    catch (Exception e) { this.mediaMime = "application/octet-stream"; }
   }
-  @Transient
   public void setMediaData(byte[] a) { this.mediaData = (a == null) ? null : a.clone(); }
   public String getMediaData() 
   { 
     if (this.mediaData == null) { return ""; } 
     
-    return "data:" + this.mediaMime + "," + Base64.getEncoder().encodeToString(this.mediaData); 
+    return "data:" + this.mediaMime + ";base64," + Base64.getEncoder().encodeToString(this.mediaData); 
   }
   @Transient
   public byte[] getMediaDataAsBinary() { return this.mediaData; }

+ 68 - 2
src/main/java/fr/triplea/demovote/web/controller/PresentationController.java

@@ -21,6 +21,8 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
@@ -35,6 +37,7 @@ import fr.triplea.demovote.dao.CategorieRepository;
 import fr.triplea.demovote.dao.PresentationRepository;
 import fr.triplea.demovote.dao.ProductionRepository;
 import fr.triplea.demovote.dto.MessagesTransfer;
+import fr.triplea.demovote.dto.PresentationFile;
 import fr.triplea.demovote.dto.ProductionItem;
 import fr.triplea.demovote.dto.ProductionShort;
 import fr.triplea.demovote.model.Categorie;
@@ -46,10 +49,9 @@ import jakarta.servlet.http.HttpServletRequest;
 @RequestMapping("/presentation")
 public class PresentationController 
 {
-  @SuppressWarnings("unused") 
+  //@SuppressWarnings("unused") 
   private static final Logger LOG = LoggerFactory.getLogger(PresentationController.class);
 
-  // TODO préparer média à partir de l'archive uploadée, pour les présentation + flag "préparé" sur chaque production présentée
   // TODO version diaporama pour affichage sur écran de régie
   // TODO raccourci ouvrir/fermer/calculer les votes
   
@@ -434,4 +436,68 @@ public class PresentationController
     return ResponseEntity.notFound().build(); 
   }
   
+  
+  
+
+  @GetMapping(value = "/formfile/{id}")
+  @PreAuthorize("hasRole('USER')")
+  public ResponseEntity<PresentationFile> getFormFile(@PathVariable int id)
+  { 
+    Presentation found = presentationRepository.findByProduction(id);
+    
+    if (found != null) 
+    { 
+      return ResponseEntity.ok(new PresentationFile(found.getProduction().getNumeroProduction(), found.getEtatMedia(), found.getMediaMime(), found.getMediaData(), "")); 
+    }
+    
+    return ResponseEntity.notFound().build();
+  }
+
+  @PutMapping(value = "/upload/{id}")
+  @PreAuthorize("hasRole('ADMIN')")
+  public ResponseEntity<Object> update(@PathVariable int id, @RequestBody(required = true) PresentationFile presentation, HttpServletRequest request) 
+  { 
+    Locale locale = localeResolver.resolveLocale(request);
+
+    Presentation found = presentationRepository.findByProduction(id);
+    
+    if (found != null)
+    {
+      if (presentation.mediaData() != null)
+      {
+        int etat = presentation.etatMedia();
+        String nom = presentation.mediaName();
+         
+        if (presentation.mediaData() == null) { etat = 0; }
+        
+        MessagesTransfer mt = new MessagesTransfer();
+        
+        switch (etat)
+        {
+        case 1: 
+          found.setEtatMedia(1); 
+          found.setMediaData(presentation.mediaData(), nom);
+          mt.setInformation(messageSource.getMessage("show.file.loaded", null, locale));
+          break;
+        case 2: 
+          found.setEtatMedia(2);
+          found.setMediaData(null, null);
+          mt.setInformation(messageSource.getMessage("show.file.acknowlegded", null, locale));
+          break;
+        default: 
+          found.setEtatMedia(0); 
+          found.setMediaData(null, null);
+          mt.setInformation(messageSource.getMessage("show.file.cleaned", null, locale));
+          break;
+        }
+
+        presentationRepository.save(found);
+
+        return ResponseEntity.ok(mt);
+      }
+    }
+    
+    return ResponseEntity.notFound().build();
+  }
+
 }

+ 1 - 1
src/main/java/fr/triplea/demovote/web/controller/ProductionController.java

@@ -50,7 +50,7 @@ import jakarta.servlet.http.HttpServletRequest;
 @RequestMapping("/production")
 public class ProductionController 
 {
-  @SuppressWarnings("unused") 
+  //@SuppressWarnings("unused") 
   private static final Logger LOG = LoggerFactory.getLogger(ProductionController.class);
 
   @Autowired

+ 5 - 1
src/main/resources/langs/messages_en.properties

@@ -40,4 +40,8 @@ show.pdf.groups=Group(s)
 show.pdf.manager=Manager
 show.pdf.comments=Comments
 show.pdf.private=Private informations
-show.pdf.productions=prod(s)
+show.pdf.productions=prod(s)
+
+show.file.loaded=The media for this production is uploaded.
+show.file.acknowlegded=The media for this production is known and managed externaly.
+show.file.cleaned=The media for this production is deleted.

+ 5 - 1
src/main/resources/langs/messages_fr.properties

@@ -40,4 +40,8 @@ show.pdf.groups=Groupe(s)
 show.pdf.manager=Gestionnaire
 show.pdf.comments=Commentaires
 show.pdf.private=Informations privées
-show.pdf.productions=production(s)
+show.pdf.productions=production(s)
+
+show.file.loaded=Le média de présentation pour cette production a été chargé.
+show.file.acknowlegded=Le média de présentation pour cette production est géré en externe.
+show.file.cleaned=Le média de présentation pour cette production est effacé.