XLS import logic updated, test file normalized
authorVásáry Dániel <vasary@elgekko.net>
Fri, 3 Nov 2023 20:00:57 +0000 (21:00 +0100)
committerVásáry Dániel <vasary@elgekko.net>
Fri, 3 Nov 2023 20:00:57 +0000 (21:00 +0100)
18 files changed:
mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/BrightCoveClientIT.java
mc-vod-sync/mc-vod-sync-app/src/test/java/hu/user/mcvodsync/VodXlsProcessorIT.java
mc-vod-sync/mc-vod-sync-app/src/test/resources/AMC_Selekt_jogositott_tartalmak_20230906.xlsx [deleted file]
mc-vod-sync/mc-vod-sync-app/src/test/resources/testdata.xlsx [new file with mode: 0644]
mc-vod-sync/mc-vod-sync-brightcove/mc-vod-sync-brightcove.iml
mc-vod-sync/mc-vod-sync-brightcove/src/main/java/hu/user/mcvodsync/brightcove/BrightCoveClient.java
mc-vod-sync/mc-vod-sync-db/migrations/scripts/002_create_system_tables.sql
mc-vod-sync/mc-vod-sync-db/migrations/scripts/003_create_business_tables.sql
mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/Asset.java
mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/AssetId.java [deleted file]
mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/AssetSync.java
mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/repository/AssetRepository.java
mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/repository/AssetSyncRepository.java
mc-vod-sync/mc-vod-sync-service/pom.xml
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/schedule/TaskSchedules.java
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/xls/AssetImportService.java
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/xls/AssetMapper.java
mc-vod-sync/mc-vod-sync-service/src/main/java/hu/user/mcvodsync/service/xls/VodXlsProcessor.java

index 54cc4eb33d23a9e520bc1b138ef4b755f547baaa..4bc34606c02a59fc7648825625a07860e04074ed 100644 (file)
@@ -1,6 +1,8 @@
 package hu.user.mcvodsync;
 
+import com.brightcove.cms.client.model.CreateVideoRequestBodyFields;
 import com.brightcove.cms.client.model.Playlist;
+import com.brightcove.cms.client.model.Video;
 import hu.user.mcvodsync.brightcove.BrightCoveClient;
 import lombok.extern.log4j.Log4j2;
 import org.junit.Test;
@@ -14,8 +16,6 @@ import org.springframework.test.context.junit4.SpringRunner;
 
 import java.util.List;
 
-import static org.junit.Assert.assertNotNull;
-
 @Log4j2
 @RunWith(SpringRunner.class)
 @ComponentScan("hu.user.mcvodsync")
@@ -23,21 +23,15 @@ import static org.junit.Assert.assertNotNull;
 @ActiveProfiles("dev")
 @TestPropertySource("classpath:application-dev.yaml")
 public class BrightCoveClientIT {
+
     @Autowired
     private BrightCoveClient bcClient;
 
-    @Test
-    public void testOAuth() {
-        String authToken = bcClient.createToken();
-        log.info("Token created {}", authToken);
-        assertNotNull(authToken);
-    }
 
     @Test
     public void testGetPlayLists() {
-        String authToken = bcClient.createToken();
         try {
-            List<Playlist> playLists = bcClient.getPlayLists(authToken, 0, 10);
+            List<Playlist> playLists = bcClient.getPlayLists(0, 10);
 
             playLists.forEach(playList -> {
                 log.info(playList.getName());
@@ -48,4 +42,76 @@ public class BrightCoveClientIT {
         }
     }
 
+    @Test
+    public void testGetVideos() {
+        try {
+            List<Video> videos = bcClient.getVideos(0, 10);
+
+            videos.forEach(video -> {
+                log.info("{} ref: {} {} {}", video.getId(), video.getReferenceId(), video.getName(), video.getState());
+            });
+
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+    @Test
+    public void testGetVideoById() {
+        try {
+            Video video = bcClient.getVideoById("6328122715112");
+            log.info("{} {} {}", video.getId(), video.getReferenceId(), video.getName());
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+    @Test
+    public void testGetVideosById() {
+        try {
+            List<Video> videos = bcClient.getVideosById("6328122715112,6339727091112");
+            videos.forEach(video -> {
+                log.info("{} {} {}", video.getId(), video.getReferenceId(), video.getName());
+            });
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+
+    @Test
+    public void testCreateVideo() {
+        try {
+            CreateVideoRequestBodyFields fields = new CreateVideoRequestBodyFields();
+            fields.setName("TEST video 00001");
+            fields.setReferenceId("MCVODSYNC00001");
+            fields.setState(CreateVideoRequestBodyFields.StateEnum.INACTIVE);
+            fields.setEconomics(CreateVideoRequestBodyFields.EconomicsEnum.FREE);
+            Video video = bcClient.createVideo(fields);
+            log.info("{} {} {}", video.getId(), video.getReferenceId(), video.getName());
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+    @Test
+    public void testGetVideoByRefId() {
+        try {
+            Video video = bcClient.getVideoById("ref:MCVODSYNC00001");
+            log.info("{} {} {}", video.getId(), video.getReferenceId(), video.getName());
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+    @Test
+    public void testDeleteVideo() {
+        try {
+            bcClient.deleteVideo("ref:MCVODSYNC00001");
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+
 }
index 0baa47bb52a5c89210d54b6d9b2f555ec200f0fc..4b602bd2602bb604f49c93b8fd32223e0f93f95d 100644 (file)
@@ -5,6 +5,8 @@
 
 package hu.user.mcvodsync;
 
+import hu.user.mcvodsync.db.repository.AssetRepository;
+import hu.user.mcvodsync.service.xls.ImportSummary;
 import hu.user.mcvodsync.service.xls.VodXlsProcessor;
 import lombok.extern.log4j.Log4j2;
 import org.junit.Test;
@@ -19,6 +21,10 @@ import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 
 @Log4j2
@@ -28,12 +34,25 @@ import java.nio.file.Paths;
 @TestPropertySource("classpath:application-dev.yaml")
 public class VodXlsProcessorIT {
     @Autowired
-    VodXlsProcessor vodXlsProcessor;
+    private VodXlsProcessor vodXlsProcessor;
+
+    @Autowired
+    private AssetRepository assetRepository;
+
+    @Test
+    public void queryPlayLists() {
+        List<String> playlists = assetRepository.queryDistinctPlaylists();
+        assertNotNull(playlists);
+
+        List<String> assets = assetRepository.queryPlaylistsAssets(playlists.get(0));
+        assertNotNull(assets);
+    }
 
     @Test
     public void processXLS() throws IOException {
-        Path xlsFile = Paths.get("src/test/resources/AMC_Selekt_jogositott_tartalmak_20230906.xlsx");
-        vodXlsProcessor.process(xlsFile.getFileName().toString(), Files.readAllBytes(xlsFile));
+        Path xlsFile = Paths.get("src/test/resources/testdata.xlsx");
+        ImportSummary process = vodXlsProcessor.process(xlsFile.getFileName().toString(), Files.readAllBytes(xlsFile));
+        assertEquals(process.getAll(), process.getSuccess());
     }
 
 }
diff --git a/mc-vod-sync/mc-vod-sync-app/src/test/resources/AMC_Selekt_jogositott_tartalmak_20230906.xlsx b/mc-vod-sync/mc-vod-sync-app/src/test/resources/AMC_Selekt_jogositott_tartalmak_20230906.xlsx
deleted file mode 100644 (file)
index 3c28ea2..0000000
Binary files a/mc-vod-sync/mc-vod-sync-app/src/test/resources/AMC_Selekt_jogositott_tartalmak_20230906.xlsx and /dev/null differ
diff --git a/mc-vod-sync/mc-vod-sync-app/src/test/resources/testdata.xlsx b/mc-vod-sync/mc-vod-sync-app/src/test/resources/testdata.xlsx
new file mode 100644 (file)
index 0000000..51429a7
Binary files /dev/null and b/mc-vod-sync/mc-vod-sync-app/src/test/resources/testdata.xlsx differ
index 888959e25f1154c444bec8bf480904c42bb9df28..cc9d6c2438a582a81ae1018e3ab426f250617c0b 100644 (file)
@@ -1,9 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module version="4">
-  <component name="AdditionalModuleElements">
-    <content url="file://$MODULE_DIR$" dumb="true">
-      <sourceFolder url="file://$MODULE_DIR$/generated" isTestSource="false" generated="true" />
-      <sourceFolder url="file://$MODULE_DIR$/src/main/generated" isTestSource="false" generated="true" />
-    </content>
+  <component name="SonarLintModuleSettings">
+    <option name="uniqueId" value="55ebe799-fcdc-47c7-96d3-ffde0937b72e" />
   </component>
 </module>
\ No newline at end of file
index d5285bb46248df406172954fc886cb345b6bd4d4..60def14aca7b834e17b98ac62d5b2daa96158a7e 100644 (file)
@@ -1,25 +1,39 @@
 package hu.user.mcvodsync.brightcove;
 
 import com.brightcove.cms.client.api.PlaylistsApi;
+import com.brightcove.cms.client.api.VideosApi;
+import com.brightcove.cms.client.model.CreateVideoRequestBodyFields;
 import com.brightcove.cms.client.model.Playlist;
+import com.brightcove.cms.client.model.Video;
 import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.oltu.oauth2.client.OAuthClient;
 import org.apache.oltu.oauth2.client.URLConnectionClient;
 import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
 import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
 import org.apache.oltu.oauth2.common.message.types.GrantType;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.MediaType;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
 import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.HttpClientErrorException;
 import org.springframework.web.client.RestClientException;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 @Log4j2
 @Service
 public class BrightCoveClient {
+    private String authToken;
+    public static final String BEARER = "Bearer ";
     private final PlaylistsApi playListApi = new PlaylistsApi();
 
+    private final VideosApi videosApi = new VideosApi();
+
     @Autowired
     private ApiProperties apiProperties;
 
@@ -42,11 +56,97 @@ public class BrightCoveClient {
         return token;
     }
 
+    private String getToken() {
+        if (StringUtils.isBlank(authToken)) {
+            authToken = BEARER + createToken();
+        }
+        return authToken;
+    }
 
-    public List<Playlist> getPlayLists(String authToken, int offset, int limit) throws RestClientException {
+    public List<Playlist> getPlayLists(int offset, int limit) throws RestClientException {
         String q = null;
         String sort = null;
-        return playListApi.getPlaylists(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE,
-                "Bearer " + authToken, limit, offset, q, sort);
+        return playListApi.getPlaylists(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE, getToken(), limit, offset, q, sort);
     }
+
+    public List<Video> getVideos(int offset, int limit) throws RestClientException {
+        String sort = null;
+        String query = null;
+        return videosApi.getVideos(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE,
+                getToken(), limit, offset, sort, query);
+    }
+
+    public Video getVideoById(String id) throws RestClientException {
+        return videosApi.getVideoByIdOrReferenceId(apiProperties.getAccountId(), "/" + id, MediaType.APPLICATION_JSON_VALUE,
+                getToken(), true);
+    }
+
+    public List<Video> getVideosById(String id) throws RestClientException {
+        return getVideoByIdOrReferenceIdWithHttpInfo(apiProperties.getAccountId(), "/" + id, MediaType.APPLICATION_JSON_VALUE,
+                getToken(), true).getBody();
+    }
+
+
+    public Video createVideo(CreateVideoRequestBodyFields fields) {
+        return videosApi.createVideo(apiProperties.getAccountId(), MediaType.APPLICATION_JSON_VALUE, getToken(), fields);
+    }
+
+    public void deleteVideo(String id) {
+        videosApi.deleteVideo(apiProperties.getAccountId(), "/" + id, MediaType.APPLICATION_JSON_VALUE, getToken());
+    }
+
+    private ResponseEntity<List<Video>> getVideoByIdOrReferenceIdWithHttpInfo(String accountId, String videoIds, String contentType, String authorization, Boolean includeVariants) throws RestClientException {
+        Object postBody = null;
+
+        // verify the required parameter 'accountId' is set
+        if (accountId == null) {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'accountId' when calling getVideoByIdOrReferenceId");
+        }
+
+        // verify the required parameter 'videoIds' is set
+        if (videoIds == null) {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'videoIds' when calling getVideoByIdOrReferenceId");
+        }
+
+        // verify the required parameter 'contentType' is set
+        if (contentType == null) {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'contentType' when calling getVideoByIdOrReferenceId");
+        }
+
+        // verify the required parameter 'authorization' is set
+        if (authorization == null) {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'authorization' when calling getVideoByIdOrReferenceId");
+        }
+
+        // create path and map variables
+        final Map<String, Object> uriVariables = new HashMap<String, Object>();
+        uriVariables.put("account_id", accountId);
+        uriVariables.put("video_ids", videoIds);
+
+        final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
+        final HttpHeaders headerParams = new HttpHeaders();
+        final MultiValueMap<String, String> cookieParams = new LinkedMultiValueMap<String, String>();
+        final MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<String, Object>();
+
+        queryParams.putAll(videosApi.getApiClient().parameterToMultiValueMap(null, "include_variants", includeVariants));
+
+        if (contentType != null)
+            headerParams.add("Content-Type", videosApi.getApiClient().parameterToString(contentType));
+        if (authorization != null)
+            headerParams.add("Authorization", videosApi.getApiClient().parameterToString(authorization));
+
+        final String[] localVarAccepts = {
+                "application/json"
+        };
+        final List<MediaType> localVarAccept = videosApi.getApiClient().selectHeaderAccept(localVarAccepts);
+        final String[] contentTypes = {};
+        final MediaType localVarContentType = videosApi.getApiClient().selectHeaderContentType(contentTypes);
+
+        String[] authNames = new String[]{"BC_OAuth2"};
+
+        ParameterizedTypeReference<List<Video>> returnType = new ParameterizedTypeReference<List<Video>>() {
+        };
+        return videosApi.getApiClient().invokeAPI("/v1/accounts/{account_id}/videos{video_ids}", HttpMethod.GET, uriVariables, queryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, authNames, returnType);
+    }
+
 }
index db08459c2f35a18b480103e8172b85197b2902c5..9e37e88fa807e64a11912f47d5fec1a8fc5b754a 100644 (file)
@@ -1,6 +1,6 @@
 -- // Create system tables
 -- Migration SQL that makes the change goes here.
-CREATE TABLE ASSOCIATE (
+CREATE TABLE associate (
     id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
     name VARCHAR(255),
     login VARCHAR(255),
@@ -9,11 +9,11 @@ CREATE TABLE ASSOCIATE (
     CONSTRAINT pk_associate PRIMARY KEY (id)
 );
 
-INSERT INTO ASSOCIATE
+INSERT INTO associate
     (name, login, password, active)
 VALUES
     ('Test User', 'user', 'password', 1);
 
 -- //@UNDO
 -- SQL to undo the change goes here.
-DROP TABLE ASSOCIATE;
+DROP TABLE associate;
index d6e5c2285eda390e076f5b6612d2081cfa27993d..e7695e11c0fa960869618580d011d3fec72d1856 100644 (file)
@@ -1,7 +1,7 @@
 -- // Create business tables
 -- Migration SQL that makes the change goes here.
 
-CREATE TABLE UPLOAD_FILE (
+CREATE TABLE upload_file (
     id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
     created TIMESTAMP,
     name VARCHAR(255),
@@ -10,34 +10,55 @@ CREATE TABLE UPLOAD_FILE (
     CONSTRAINT pk_uploadfile PRIMARY KEY (id)
 );
 
-CREATE TABLE ASSET (
-    episode_id VARCHAR(20) NOT NULL,
+CREATE TABLE asset (
+    catalog_id VARCHAR(20) NOT NULL,
     season_id BIGINT NOT NULL,
     series_id BIGINT NOT NULL,
-    hub_info VARCHAR(255) NOT NULL,
-    episode_title VARCHAR(255) NOT NULL,
-    season_title VARCHAR(255),
-    series_title VARCHAR(255),
+    sunset DATE NOT NULL,
+    sunrise DATE NOT NULL,
+    playlist VARCHAR(100) NOT NULL,
+    hub_info VARCHAR(100),
+    prog_local_title VARCHAR(255) NOT NULL,
+    season_local_title VARCHAR(255),
+    series_local_title VARCHAR(255),
     season_nr INTEGER,
     episode_nr INTEGER,
     production_year INTEGER,
     country VARCHAR(1000),
+    orig_language VARCHAR(20),
+    content_type VARCHAR(50),
+    content_source VARCHAR(50),
     age_rating VARCHAR(10),
-    CONSTRAINT pk_asset PRIMARY KEY (episode_id, season_id, series_id)
+    CONSTRAINT pk_catalog_id PRIMARY KEY (catalog_id)
 );
+CREATE INDEX idx_asset_playlist ON asset(playlist);
 
-CREATE TABLE ASSET_SYNC (
-    execution_id VARCHAR(36) NOT NULL,
-    episode_id VARCHAR(20) NOT NULL,
-    season_id BIGINT NOT NULL,
-    series_id BIGINT NOT NULL,
+CREATE TABLE asset_sync (
+    id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    catalog_id VARCHAR(20) NOT NULL,
+    imported TIMESTAMP NOT NULL,
+    sync_type VARCHAR(6) NOT NULL,
+    exported_success TIMESTAMP,
+    exported_error TIMESTAMP,
+    CONSTRAINT pk_asset_sync PRIMARY KEY (id)
+);
+CREATE INDEX idx_asset_sync_exported_success ON asset_sync(exported_success);
+
+CREATE TABLE playlist_sync (
+    id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    playlist VARCHAR(100) NOT NULL,
+    imported TIMESTAMP NOT NULL,
     sync_type VARCHAR(6) NOT NULL,
-    completed TIMESTAMP,
-    CONSTRAINT pk_asset_sync PRIMARY KEY (episode_id, season_id, series_id)
+    exported_success TIMESTAMP,
+    exported_error TIMESTAMP,
+    CONSTRAINT pk_playlist_sync PRIMARY KEY (id)
 );
+CREATE INDEX idx_playlist_sync_exported_success ON asset_sync(exported_success);
+
 
 -- //@UNDO
 -- SQL to undo the change goes here.
-DROP TABLE ASSET;
-DROP TABLE ASSET_SYNC;
-DROP TABLE UPLOAD_FILE;
+DROP TABLE asset;
+DROP TABLE asset_sync;
+DROP TABLE playlist_sync;
+DROP TABLE upload_file;
index 314e4cd979246721584719a438249a564689c1fb..cf93512b3cb315e7e0e0003d37a5a4d49cd66e10 100644 (file)
@@ -5,8 +5,8 @@ import lombok.*;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
-import javax.persistence.IdClass;
 import java.io.Serializable;
+import java.sql.Date;
 
 @Getter
 @Setter
@@ -15,43 +15,45 @@ import java.io.Serializable;
 @ToString
 @NoArgsConstructor
 @AllArgsConstructor
-@IdClass(AssetId.class)
 public class Asset implements Serializable {
     @Id
-    private String episodeId;
+    private String catalogId;
 
-    @Id
     private Long seasonId;
 
-    @Id
     private Long seriesId;
 
-
     @Column(nullable = false)
-    private String hubInfo;
-
+    private Date sunset;
 
     @Column(nullable = false)
-    private String episodeTitle;
+    private Date sunrise;
 
+    @Column(nullable = false)
+    private String playlist;
 
-    private String seasonTitle;
+    private String hubInfo;
 
+    @Column(nullable = false)
+    private String progLocalTitle;
 
-    private String seriesTitle;
+    private String seasonLocalTitle;
 
+    private String seriesLocalTitle;
 
     private Integer seasonNr;
 
-
     private Integer episodeNr;
 
-
     private Integer productionYear;
 
-
     private String country;
 
+    private String origLanguage;
+
+    private String contentType;
+
+    private String contentSource;
 
     private String ageRating;
 }
diff --git a/mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/AssetId.java b/mc-vod-sync/mc-vod-sync-db/src/main/java/hu/user/mcvodsync/db/AssetId.java
deleted file mode 100644 (file)
index 5ff15f9..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-package hu.user.mcvodsync.db;
-
-import lombok.*;
-
-import javax.persistence.Column;
-import java.io.Serializable;
-
-@Getter
-@Setter
-@Builder
-@ToString
-@NoArgsConstructor
-@AllArgsConstructor
-public class AssetId implements Serializable {
-
-    @Column(nullable = false)
-    private String episodeId;
-
-    @Column(nullable = false)
-    private Long seasonId;
-
-    @Column(nullable = false)
-    private Long seriesId;
-
-}
index f9fc2a41d78002b1c382433c847bbab8a2f8130c..b7bdcb1b11fe21be93036c1ad968220334676978 100644 (file)
@@ -13,24 +13,21 @@ import java.util.Date;
 @ToString
 @NoArgsConstructor
 @AllArgsConstructor
-@IdClass(AssetId.class)
 public class AssetSync implements Serializable {
-
-    @Column(nullable = false)
-    private String executionId;
-
     @Id
-    private String episodeId;
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    Long id;
 
-    @Id
-    private Long seasonId;
+    private String catalogId;
 
-    @Id
-    private Long seriesId;
+    @Column(nullable = false)
+    private Date imported;
 
     @Enumerated(EnumType.STRING)
     @Column(nullable = false)
     private SyncType syncType;
 
-    private Date completed;
+    private Date exportedSuccess;
+
+    private Date exportedError;
 }
index 6fb2e7704ea3cdacf71dc842f8bf4b167581e385..de660d3c920350831731528c05e8574ae83c237c 100644 (file)
@@ -1,8 +1,17 @@
 package hu.user.mcvodsync.db.repository;
 
 import hu.user.mcvodsync.db.Asset;
-import hu.user.mcvodsync.db.AssetId;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+public interface AssetRepository extends JpaRepository<Asset, String> {
+
+    @Query("SELECT DISTINCT(a.playlist) FROM Asset a ORDER BY a.playlist")
+    List<String> queryDistinctPlaylists();
+
+    @Query("SELECT a.catalogId FROM Asset a WHERE a.playlist = :playlist ORDER BY a.seasonNr, a.episodeNr")
+    List<String> queryPlaylistsAssets(String playlist);
 
-public interface AssetRepository extends JpaRepository<Asset, AssetId> {
 }
index 048fa0389dabe1ea91aec83266a680b01cd5ac53..bf27cd195d728c988b33f60a188c80f02ce3e2c1 100644 (file)
@@ -1,8 +1,7 @@
 package hu.user.mcvodsync.db.repository;
 
-import hu.user.mcvodsync.db.AssetId;
 import hu.user.mcvodsync.db.AssetSync;
 import org.springframework.data.jpa.repository.JpaRepository;
 
-public interface AssetSyncRepository extends JpaRepository<AssetSync, AssetId> {
+public interface AssetSyncRepository extends JpaRepository<AssetSync, String> {
 }
index 5d0ed5a1c48dbc1b9fcaf0ddccae6ae405a08d07..0dbfe32e87daf827ac21b825fbb5f9e4f6982789 100644 (file)
             <artifactId>fastexcel-reader</artifactId>
             <version>0.15.7</version>
         </dependency>
+        <dependency>
+            <groupId>org.threeten</groupId>
+            <artifactId>threetenbp</artifactId>
+            <version>1.4.0</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 </project>
index 118328219008f3d19a32e74e9eda0e0bca3f111b..5c8756086be51ab133ceaec52bfd4d06b1da719d 100644 (file)
@@ -6,9 +6,9 @@ import org.springframework.stereotype.Service;
 @Service
 public class TaskSchedules {
 
-    @Scheduled(fixedDelay = 5000)
+    @Scheduled(fixedDelay = 50000)
     public void scheduleFixedDelayTask() {
-        System.out.println(
-                "Fixed delay task - " + System.currentTimeMillis() / 1000);
+//        System.out.println(
+//                "Fixed delay task - " + System.currentTimeMillis() / 1000);
     }
 }
index 723d866b1f46cb76236e0d5a296c465476636653..6539be839b7cff36257d4b52bd81a44391be7129 100644 (file)
@@ -2,7 +2,6 @@ package hu.user.mcvodsync.service.xls;
 
 
 import hu.user.mcvodsync.db.Asset;
-import hu.user.mcvodsync.db.AssetId;
 import hu.user.mcvodsync.db.AssetSync;
 import hu.user.mcvodsync.db.SyncType;
 import hu.user.mcvodsync.db.repository.AssetRepository;
@@ -13,52 +12,68 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Objects;
-import java.util.Optional;
+import java.time.Instant;
+import java.util.*;
 
 @Log4j2
 @Service
 public class AssetImportService {
     @Autowired
-    AssetRepository assetRepository;
+    private AssetRepository assetRepository;
 
     @Autowired
-    AssetSyncRepository assetSyncRepository;
+    private AssetSyncRepository assetSyncRepository;
 
     @Autowired
-    EntityDataService<Asset> entityDataService;
+    private EntityDataService<Asset> entityDataService;
+
+    private Map<String, List<String>> currentPlaylists;
+
+    public void prepare() {
+        currentPlaylists = getPlayLists();
+    }
+
+    private Map<String, List<String>> getPlayLists() {
+        Map<String, List<String>> result = new HashMap<>();
+        List<String> playlistNames = assetRepository.queryDistinctPlaylists();
+        playlistNames.forEach(playlist -> {
+            List<String> playlistsAssets = assetRepository.queryPlaylistsAssets(playlist);
+            result.put(playlist, playlistsAssets);
+        });
+        return result;
+    }
 
     @Transactional
-    public void processAsset(String executionId, Asset asset) {
-        AssetId assetId = AssetId.builder()
-                .episodeId(asset.getEpisodeId())
-                .seasonId(asset.getSeasonId())
-                .seriesId(asset.getSeriesId())
-                .build();
-        Optional<Asset> optionalEntity = assetRepository.findById(assetId);
+    public void processAsset(Asset asset, ImportSummary summary) {
+        Optional<Asset> optionalEntity = assetRepository.findById(asset.getCatalogId());
 
         AssetSync assetSync = AssetSync.builder()
-                .executionId(executionId)
-                .episodeId(asset.getEpisodeId())
-                .seasonId(asset.getSeasonId())
-                .seriesId(asset.getSeriesId())
+                .imported(Date.from(Instant.now()))
+                .catalogId(asset.getCatalogId())
+                .syncType(SyncType.INSERT)
                 .build();
 
         if (optionalEntity.isPresent()) {
             boolean areDifferent = entityDataService.areDifferent(asset, optionalEntity.get());
             if (areDifferent) {
-//                log.info("History UPDATE registered for {}", assetId);
                 assetSync.setSyncType(SyncType.UPDATE);
             }
-        } else {
-//            log.info("History INSERT registered for {}", assetId);
-            assetSync.setSyncType(SyncType.INSERT);
         }
 
-        if (Objects.nonNull(assetSync.getSyncType())) {
-            assetSyncRepository.save(assetSync);
+        assetRepository.saveAndFlush(asset);
+        assetSyncRepository.saveAndFlush(assetSync);
+
+        if (assetSync.getSyncType() == SyncType.UPDATE) {
+            summary.incUpdated();
+        }
+        if (assetSync.getSyncType() == SyncType.INSERT) {
+            summary.incInserted();
         }
-        assetRepository.save(asset);
     }
 
+    public void finish() {
+        Map<String, List<String>> newPlaylists = getPlayLists();
+
+        //CollectionUtils.isEqualCollection(Collection<?> a, Collection<?> b)
+    }
 }
index 26a2e84eca81679c7dd7b460ae77a8615e47164d..74b4920c0c5f9f6ad51a21367fe68c50b30646b8 100644 (file)
@@ -1,27 +1,74 @@
 package hu.user.mcvodsync.service.xls;
 
 import hu.user.mcvodsync.db.Asset;
+import org.apache.commons.lang3.StringUtils;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
+import org.mapstruct.Named;
 import org.mapstruct.ReportingPolicy;
 
+import java.sql.Date;
+import java.text.SimpleDateFormat;
 import java.util.Map;
 
 
 @Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
 public interface AssetMapper {
-    @Mapping(target = "episodeId", source = "CATALOG_ID")
-    @Mapping(target = "seasonId", source = "SEASON_CATALOG_ID")
-    @Mapping(target = "seriesId", source = "SERIES_GROUP_CATALOG_ID")
+    SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
+
+    @Mapping(target = "catalogId", source = "CATALOG_ID")
+    @Mapping(target = "seasonId", source = "SEASON_CATALOG_ID", qualifiedByName = "mapNullableNumber")
+    @Mapping(target = "seriesId", source = "SERIES_GROUP_CATALOG_ID", qualifiedByName = "mapNullableNumber")
+    @Mapping(target = "sunset", source = "Sunset Date", qualifiedByName = "mapSunset")
+    @Mapping(target = "sunrise", source = "Sunrise Date", qualifiedByName = "mapSunrise")
+    @Mapping(target = "playlist", source = "PLAYLIST_NAME")
     @Mapping(target = "hubInfo", source = "HUB_INFO")
-    @Mapping(target = "episodeTitle", source = "PROG_ORIG_TITLE")
-    @Mapping(target = "seasonTitle", source = "SEASON_ORIG_TITLE")
-    @Mapping(target = "seriesTitle", source = "SER_GROUP_ORIG_TITLE")
-    @Mapping(target = "seasonNr", source = "SEASON_NUMBER")
-    @Mapping(target = "episodeNr", source = "EPISODE_NR")
-    @Mapping(target = "ageRating", source = "AGE_RATING")
+    @Mapping(target = "progLocalTitle", source = "PROG_LOCAL_TITLE")
+    @Mapping(target = "seasonLocalTitle", source = "SEASON_LOCAL_TITLE")
+    @Mapping(target = "seriesLocalTitle", source = "SERIES_GROUP_LOCAL_TITLE")
+    @Mapping(target = "seasonNr", source = "SEASON_NUMBER", qualifiedByName = "mapNullableNumber")
+    @Mapping(target = "episodeNr", source = "EPISODE_NR", qualifiedByName = "mapNullableNumber")
+    @Mapping(target = "productionYear", source = "PRODUCTION_YEAR", qualifiedByName = "mapNullableNumber")
     @Mapping(target = "country", source = "COUNTRY_OF_ORIGIN")
-    @Mapping(target = "productionYear", source = "PRODUCTION_YEAR")
+    @Mapping(target = "origLanguage", source = "ORIGINAL_LANGUAGE")
+    @Mapping(target = "contentType", source = "CONTENT_TYPE")
+    @Mapping(target = "contentSource", source = "CONTENT_SOURCE")
+    @Mapping(target = "ageRating", source = "AGE_RATING")
     Asset toEntity(Map<String, String> xlsRowData);
 
+    @Named("mapNullableNumber")
+    static long mapNullableNumber(String numberValue) {
+        long result = 0;
+        try {
+            if (StringUtils.isNotBlank(numberValue)) {
+                result = Long.parseLong(numberValue);
+            }
+        } catch (Exception ignored) {
+        }
+        return result;
+    }
+
+
+    @Named("mapSunrise")
+    static Date mapSunrise(String numberValue) {
+        long longValue = 0;
+        try {
+            longValue = Long.parseLong(numberValue);
+        } catch (Exception ignored) {
+        }
+        long javaDateValue = (longValue - 25569) * 86400 * 1000;
+        return new Date(javaDateValue);
+    }
+
+    @Named("mapSunset")
+    static Date mapSunset(String dateValue) {
+        Date result = null;
+        try {
+            if (StringUtils.isNotBlank(dateValue)) {
+                result = new Date(formatter.parse(dateValue).getTime());
+            }
+        } catch (Exception ignored) {
+        }
+        return result;
+    }
 }
index 6eb4bfc692a5e51b9c5941fb51bfac8c65676c5c..0d557c28d42c59ee070f0da93782c26574833845 100644 (file)
@@ -3,7 +3,6 @@ package hu.user.mcvodsync.service.xls;
 import hu.user.mcvodsync.db.Asset;
 import lombok.extern.log4j.Log4j2;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.time.DurationFormatUtils;
 import org.dhatim.fastexcel.reader.Cell;
 import org.dhatim.fastexcel.reader.ReadableWorkbook;
 import org.dhatim.fastexcel.reader.Row;
@@ -14,79 +13,102 @@ import org.springframework.stereotype.Service;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.time.Duration;
 import java.time.Instant;
-import java.util.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 @Log4j2
 @Service
 public class VodXlsProcessor {
-    private final List<String> mappings = Collections.emptyList();
     private List<Cell> headers;
 
     @Autowired
-    AssetMapper assetMapper;
+    private AssetMapper assetMapper;
 
     @Autowired
-    AssetImportService assetImportService;
+    private AssetImportService assetImportService;
 
-    public void process(String fileName, byte[] xlsData) {
-        Instant start = Instant.now();
-        String executionId = UUID.randomUUID().toString();
+    public ImportSummary process(String fileName, byte[] xlsData) {
+        ImportSummary summary = ImportSummary.builder().started(Instant.now()).build();
         try (InputStream is = new ByteArrayInputStream(xlsData);
              ReadableWorkbook wb = new ReadableWorkbook(is)) {
             Sheet sheet = wb.getFirstSheet();
-
             try (Stream<Row> rows = sheet.openStream()) {
                 rows.forEach(row -> {
                     if (row.getRowNum() == 1) {
+                        assetImportService.prepare();
                         headers = getHeaders(row);
                     } else {
-                        processRow(executionId, row);
+                        summary.incAll();
+                        processRow(row, summary);
                     }
                 });
             }
+            assetImportService.finish();
+
         } catch (IOException e) {
             log.error("Excel file reading error from {}. System message: {}", fileName, e.getMessage());
         }
-        Duration executionDuration = Duration.between(start, Instant.now());
-        String duration = DurationFormatUtils.formatDuration(executionDuration.toMillis(), "H:mm:ss", true);
-        log.info("Processing took {}", duration);
+        summary.setFinished(Instant.now());
+        log.info(summary);
+        return summary;
     }
 
     private List<Cell> getHeaders(Row row) {
         return row.stream().collect(Collectors.toList());
     }
 
-    private void processRow(String executionId, Row r) {
+    private void processRow(Row r, ImportSummary summary) {
         Map<String, String> rowData = new HashMap<>();
         r.stream().filter(Objects::nonNull).forEach(c -> {
             try {
+                String header = headers.get(c.getColumnIndex()).getRawValue();
                 String data = c.getRawValue();
-                rowData.put(headers.get(c.getColumnIndex()).getRawValue(), data);
+                rowData.put(header, data);
             } catch (Exception e) {
                 log.error("Cell error!", e);
             }
         });
-        Asset asset = assetMapper.toEntity(rowData);
-        if (Objects.isNull(asset.getSeasonId())) {
-            asset.setSeasonId(0L);
-        }
-        if (Objects.isNull(asset.getSeriesId())) {
-            asset.setSeriesId(0L);
-        }
 
-        if (StringUtils.isBlank(asset.getHubInfo()) || StringUtils.isBlank(asset.getEpisodeTitle())) {
-            //log.error("Hub not defined for {}", asset);
-        } else {
-            try {
-                assetImportService.processAsset(executionId, asset);
-            } catch (Exception e) {
-                log.error("Processing error for {}", asset);
+        Asset asset = null;
+        try {
+            asset = assetMapper.toEntity(rowData);
+            if (isAssetValid(asset)) {
+                assetImportService.processAsset(asset, summary);
             }
+            summary.incSuccess();
+        } catch (Exception e) {
+            summary.incError();
+            log.error("Processing error for {}", asset, e);
+        }
+    }
+
+    private boolean isAssetValid(Asset asset) {
+        if (StringUtils.isBlank(asset.getCatalogId())) {
+            log.warn("Catalog ID not defined for {}", asset);
+            return false;
+        }
+        if (StringUtils.isBlank(asset.getPlaylist())) {
+            log.warn("Playlist not defined for {}", asset);
+            return false;
+        }
+        if (StringUtils.isBlank(asset.getProgLocalTitle())) {
+            log.warn("Prog local title not defined for {}", asset);
+            return false;
+        }
+        if (Objects.isNull(asset.getSunset())) {
+            log.warn("Sunset not defined for {}", asset);
+            return false;
+        }
+        if (Objects.isNull(asset.getSunrise())) {
+            log.warn("Sunrise not defined for {}", asset);
+            return false;
         }
+        return true;
     }
 
 }