From: elgekko Date: Thu, 1 Dec 2022 17:25:47 +0000 (+0100) Subject: Dark style in progress, Octopus sync optimized X-Git-Url: http://git.useribm.hu/?a=commitdiff_plain;h=9fb34a702b034e14799292a32ad90113c9615c5d;p=mediacube.git Dark style in progress, Octopus sync optimized --- diff --git a/server/-product/.project b/server/-product/.project index 81835c3d..61c030e0 100644 --- a/server/-product/.project +++ b/server/-product/.project @@ -1,6 +1,4 @@ - - -product diff --git a/server/-product/production/HIRTV/jobs/executors.xml b/server/-product/production/HIRTV/jobs/executors.xml index b22f5689..08332f19 100644 --- a/server/-product/production/HIRTV/jobs/executors.xml +++ b/server/-product/production/HIRTV/jobs/executors.xml @@ -6,6 +6,8 @@ + + diff --git a/server/-product/production/HIRTV/jobs/schedules.json b/server/-product/production/HIRTV/jobs/schedules.json index b31018c7..48954e2a 100644 --- a/server/-product/production/HIRTV/jobs/schedules.json +++ b/server/-product/production/HIRTV/jobs/schedules.json @@ -1,28 +1,5 @@ { "joblist": [ - { - "active": true, - "executeimmediate": false, - "name" : "Lejárt ISISLON/PROMO_NLE mappák törlése", - "template": "delete-promo-materials.xml", - "cronexpression": "0 0 6 * * ?", - "parameters": [ - {"name": "sourcePath", "value": "/mnt/ISILON/PROMO_NLE", "type": "java.lang.String"} - ] - }, - { - "template": "dummy-test-job.xml", - "name": "dummy test job", - "active": true, - "executeimmediate": false, - "parameters": [ - { - "name": "param1", "value": "Jozsi", - "type": "java.lang.String" - } - ], - "cronexpression": "0/3 * * * * ?" - }, { "active": false, "cronexpression": "0/2 * * * * ?", @@ -36,53 +13,12 @@ ] }, { - "active": false, "cronexpression": "0/2 * * * * ?", - "template": "cancelable.xml", - "parameters": [ - { - "name": "param", - "value": 200, - "type": "java.lang.Integer" - } - ] - }, - { - "active": false, - "template": "test-fork-cancelable.xml", + "template": "sys-fork-recreate-lowres.xml", "parameters": [ { - "name": "count", - "value": 2, - "type": "java.lang.Integer" - } - ] - }, - { - "active": true, - "executeimmediate": true, - "name": "OCTOPUS adatok szinkronizálása", - "template": "sync-octopus.xml", - "cronexpression": "0/30 * * * * ?", - "parameters": [ - { - "name": "includeArchived", - "value": false, - "type": "java.lang.Boolean" - }, - { - "name": "address", - "value": "http://10.10.1.11/api/v1", - "type": "java.lang.String" - }, - { - "name": "user", - "value": "mam", - "type": "java.lang.String" - }, - { - "name": "pwd", - "value": "napocska", + "name": "localHiresPath", + "value": "c:/temp", "type": "java.lang.String" } ] diff --git a/server/-product/production/HIRTV/jobs/steps/ProjectCleanupMountedLocationStep.java b/server/-product/production/HIRTV/jobs/steps/ProjectCleanupMountedLocationStep.java deleted file mode 100644 index ce9c3c09..00000000 --- a/server/-product/production/HIRTV/jobs/steps/ProjectCleanupMountedLocationStep.java +++ /dev/null @@ -1,235 +0,0 @@ -package user.jobengine.server.steps; - -import java.io.File; -import java.io.IOException; -import java.nio.file.DirectoryStream; -import java.nio.file.FileVisitResult; -import java.nio.file.FileVisitor; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.Marker; - -import user.jobengine.server.IJobEngine; -import user.jobengine.server.IJobRuntime; -import user.jobengine.server.steps.shared.MetadataType; -import user.jobengine.server.steps.shared.MetadataTypeDetector; - -public class ProjectCleanupMountedLocationStep extends JobStep implements FileVisitor { - - private static final Logger logger = LogManager.getLogger(); - private static final String DATEFORMAT = "yyyyMMdd"; - private static final String DOT = "."; - private static final String STATUSFOLDER = ".STATUS"; - private static final String KILLDATEEXT = ".killdate"; - private Marker marker; - final int[] allCount = { 0 }; - final int[] currentCount = { 0 }; - private Path sourcePath; - private SimpleDateFormat dateFormat; - - private Date checkExpiration(List killDateFiles) { - Date killDate = null; - for (Path killDateFile : killDateFiles) { - Date currentKillDate = getKillDate(killDateFile); - if (currentKillDate == null) - continue; - if ((killDate != null && currentKillDate.after(killDate)) || killDate == null) - killDate = currentKillDate; - } - return new Date().after(killDate) ? killDate : null; - } - - @StepEntry - public Object[] execute(String sourceFolder, IJobEngine jobEngine, IJobRuntime jobRuntime) throws Exception { - marker = jobRuntime.getSessionMarker(); - sourcePath = Paths.get(sourceFolder); - DirectoryStream directoryStream = null; - if (StringUtils.isBlank(sourcePath.toString())) { - logger.error(marker, "A folyamat 'sourcePath' bemeneti paramétere üres."); - throw new NullPointerException( - "System is not configured properly, 'sourceFolder' input parameter missing."); - } - - if (!sourcePath.toFile().exists() || !sourcePath.toFile().isDirectory()) { - logger.error(marker, "A(z) {} mappa nem létezik.", sourceFolder); - throw new NullPointerException(String.format("Directory %s does not exist.", sourceFolder)); - } - try { - setProgress(1); - dateFormat = new SimpleDateFormat(DATEFORMAT); - Files.walkFileTree(sourcePath, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - allCount[0]++; - return super.visitFile(file, attrs); - } - }); - Files.walkFileTree(sourcePath, this); - } catch (Exception e) { - logger.catching(e); - logger.error(marker, "Az '{}' mappa elérése sikertelen. A rendszer hibaüzenete: {}", sourcePath, - e.getMessage()); - throw e; - } finally { - if (directoryStream != null) { - try { - directoryStream.close(); - } catch (IOException e) { - } - } - } - return null; - } - - private Date getKillDate(Path killDateFile) { - String fileName = killDateFile.getFileName().toString(); - int end = fileName.lastIndexOf(DOT); - if (end < 1) - return null; - int start = fileName.lastIndexOf(DOT, end - 1); - if (start < 0) - return null; - String strKillDate = fileName.substring(start + 1, end); - Date result = null; - if (StringUtils.isNumeric(strKillDate)) { - try { - result = dateFormat.parse(strKillDate); - } catch (ParseException e) { - logger.error(marker, - "A {} fájl 'killdate' állománya hibás formátumú, a {} karaktersorozat nem konvertálható dátummá.", - fileName, strKillDate); - return null; - } - } else - logger.error(marker, "A {} fájl 'killdate' állománya hibás formátumú, az dátum helyett ez áll: '{}'.", - fileName, strKillDate); - return result; - } - - private List getKillDateFiles(Path filePath) { - String killDateFilePattern = String.format("%s.*%s", filePath.getFileName().toString(), KILLDATEEXT); - List result = new ArrayList<>(); - Path statusPath = null; - try { - statusPath = Paths.get(filePath.getParent().toString(), STATUSFOLDER); - } catch (Exception e) { - logger.catching(e); - return null; - } - File statusPathFile = statusPath.toFile(); - if (statusPathFile.exists() && statusPathFile.isDirectory()) { - try (DirectoryStream stream = Files.newDirectoryStream(statusPath, killDateFilePattern)) { - stream.forEach(p -> result.add(p)); - } catch (Exception e) { - logger.catching(e); - } - } - Collections.sort(result); - return result; - } - - private Path getProjectRootPath(Path filePath) { - Path result = null; - if (filePath.getNameCount() > sourcePath.getNameCount()) { - String dir = filePath.getName(sourcePath.getNameCount()).toString(); - String[] tokens = dir.split("-"); - if (tokens.length != 0 && MetadataTypeDetector.GuessMetadataType(tokens[0]) == MetadataType.TrafficPromo) - result = Paths.get(sourcePath.toAbsolutePath().toString(), dir); - } - return result; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - if (dir.equals(sourcePath)) - return FileVisitResult.CONTINUE; - - Path parent = getProjectRootPath(dir); - if (parent == null) { - System.out.println("Skipping " + dir); - return FileVisitResult.SKIP_SUBTREE; - } - - return FileVisitResult.CONTINUE; - } - - private boolean processPathItem(Path filePath) { - currentCount[0]++; - int progress = currentCount[0] * 100 / allCount[0]; - setProgress(progress); - - if (filePath.toFile().isDirectory() || !filePath.toString().toUpperCase().endsWith(".EZP")) - return false; - - // level check - if (filePath.getNameCount() != sourcePath.getNameCount() + 3) { - // logger.warn(marker, "A {} fájl elérési útja a várttól eltérő.", filePath); - return false; - } - - List killDateFiles = getKillDateFiles(filePath); - if (killDateFiles == null || killDateFiles.size() == 0) { - logger.warn(marker, "A {} fájlhoz nem található 'killdate' állomány.", filePath); - return false; - } - - if (killDateFiles.size() != 1) - logger.warn(marker, - "A {} fájlhoz több 'killdate' állomány található, a legújabb dátum határozza meg a törlés időpontját.", - filePath); - - Date killDate = checkExpiration(killDateFiles); - if (killDate == null) - return false; - - Path parent = getProjectRootPath(filePath); - if (parent != null) { - Path pathToDelete = Paths.get(sourcePath.toAbsolutePath().toString(), - filePath.getName(sourcePath.getNameCount()).toString()); - try { - FileUtils.deleteDirectory(pathToDelete.toFile()); - logger.info(marker, "A {} mappa sikeresen törlődött. Lejárat: {}", pathToDelete, - dateFormat.format(killDate)); - } catch (Exception e) { - logger.error(marker, "A {} mappa törlése nem lehetséges, a rendszer üzenete: {}", pathToDelete, - e.getMessage()); - logger.error(e); - } - } - // else - // logger.warn(marker, "A {} fájlhoz nem határozható meg a törlendő - // szülőkönyvtár.", filePath); - return true; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - processPathItem(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFileFailed(Path file, IOException e) throws IOException { - logger.error(marker, "A {} fájl nem érhető el. A rendszer hibaüzenete: {}", file.toString(), e.getMessage()); - return FileVisitResult.CONTINUE; - } -} diff --git a/server/-product/production/HIRTV/jobs/steps/shared/MetadataType.java b/server/-product/production/HIRTV/jobs/steps/shared/MetadataType.java deleted file mode 100644 index 0e27bf34..00000000 --- a/server/-product/production/HIRTV/jobs/steps/shared/MetadataType.java +++ /dev/null @@ -1,5 +0,0 @@ -package user.jobengine.server.steps.shared; - -public enum MetadataType { - TrafficMaterial, TrafficPromo, TrafficAD, OctopusStory, OctopusPlaceholder, Generic -} diff --git a/server/-product/production/HIRTV/jobs/steps/shared/MetadataTypeDetector.java b/server/-product/production/HIRTV/jobs/steps/shared/MetadataTypeDetector.java deleted file mode 100644 index 9e9e6be9..00000000 --- a/server/-product/production/HIRTV/jobs/steps/shared/MetadataTypeDetector.java +++ /dev/null @@ -1,49 +0,0 @@ -package user.jobengine.server.steps.shared; - -import org.apache.commons.lang.StringUtils; - -public class MetadataTypeDetector { - - private static final String HYPHEN = "-"; - private static final String DOT = "."; - - private static final String REGEXP_TRAFFICMATERIALID = "^M{1}[0-9]{6}[A-Z]{1}"; - private static final String REGEXP_TRAFFICADID = "^R{1}[0-9]{6}[A-Z]{1}"; - private static final String REGEXP_TRAFFICPROMOID = "^P{1}[0-9]{6}[A-Z]{1}"; - private static final String REGEXP_OCTOPUSSTORYID = "^[0-9]+"; - private static final String REGEXP_OCTOPUSPLACEHOLDERID = "^[0-9]+_[0-9]+"; - private static final String REGEXP_OCTOPUSPLACEHOLDERVERSIONEDID = "^[0-9]+_[0-9]+-[0-9]{3}"; - - public static MetadataType GuessMetadataType(String id) { - if (StringUtils.isBlank(id)) - return MetadataType.Generic; - if (id.matches(REGEXP_TRAFFICMATERIALID)) - return MetadataType.TrafficMaterial; - if (id.matches(REGEXP_TRAFFICPROMOID)) - return MetadataType.TrafficPromo; - if (id.matches(REGEXP_TRAFFICADID)) - return MetadataType.TrafficAD; - if (id.matches(REGEXP_OCTOPUSSTORYID)) - return MetadataType.OctopusStory; - if (id.matches(REGEXP_OCTOPUSPLACEHOLDERID)) - return MetadataType.OctopusPlaceholder; - if (id.matches(REGEXP_OCTOPUSPLACEHOLDERVERSIONEDID)) - return MetadataType.OctopusPlaceholder; - return MetadataType.Generic; - } - - public static String truncateExtension(String name) { - String result = name; - if (result != null && result.contains(DOT)) - result = result.substring(0, result.lastIndexOf(DOT)); - return result; - } - - public static String truncateVersion(String name) { - String result = name; - if (result != null && result.contains(HYPHEN)) - result = result.split(HYPHEN)[0]; - return result; - } - -} diff --git a/server/-product/production/HIRTV/settings/mediacube.yaml b/server/-product/production/HIRTV/settings/mediacube.yaml index e192f335..356014aa 100644 --- a/server/-product/production/HIRTV/settings/mediacube.yaml +++ b/server/-product/production/HIRTV/settings/mediacube.yaml @@ -24,8 +24,8 @@ bottomTypeFilters: - name: Reklám nyers authentication: authEnabled: true - defaultUser: root - defaultPassword: password +# defaultUser: root +# defaultPassword: password adHost: 10.10.254.11 adNonSecurePort: 3268 adBaseDn: DC=intra,DC=echotv,DC=hu diff --git a/server/hu.user.mediacube.executors.tests/src/hu/user/mediacube/executors/tests/SmallTests.java b/server/hu.user.mediacube.executors.tests/src/hu/user/mediacube/executors/tests/SmallTests.java index 19bb773f..70089a5c 100644 --- a/server/hu.user.mediacube.executors.tests/src/hu/user/mediacube/executors/tests/SmallTests.java +++ b/server/hu.user.mediacube.executors.tests/src/hu/user/mediacube/executors/tests/SmallTests.java @@ -19,6 +19,7 @@ import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.time.Duration; import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; @@ -1593,9 +1594,14 @@ public class SmallTests { @Test public void test9999993() throws Exception { - Path sut = Paths.get("/opt/test/media.mxf"); - System.out.println(EscortFiles.constructMetadataPath(sut)); + System.out.println(String.format("%s LIKE('%%%s%%')", "10", "20")); + } + + @Test + public void test9999994() throws Exception { + LocalDate date = LocalDate.parse("2022-12-02T19:10:00.000+01:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME); + System.out.println(date.toString()); } } diff --git a/server/user.commons.zk/.classpath b/server/user.commons.zk/.classpath index 9c8687fb..50934149 100644 --- a/server/user.commons.zk/.classpath +++ b/server/user.commons.zk/.classpath @@ -1,5 +1,6 @@ + diff --git a/server/user.commons.zk/META-INF/MANIFEST.MF b/server/user.commons.zk/META-INF/MANIFEST.MF index 9e618fa5..32f6ee7a 100644 --- a/server/user.commons.zk/META-INF/MANIFEST.MF +++ b/server/user.commons.zk/META-INF/MANIFEST.MF @@ -47,7 +47,8 @@ Bundle-ClassPath: ., lib/zul.jar, lib/zuti.jar, lib/zweb.jar, - lib/datahandler-syntax-highlight-1.0.0.jar + lib/datahandler-syntax-highlight-1.0.0.jar, + lib/userdark-8.0.3.jar Export-Package: bsh, bsh.classpath, bsh.collection, @@ -374,6 +375,7 @@ Export-Package: bsh, org.zkoss.theme.___THEME_NAME___, org.zkoss.theme.sapphire, org.zkoss.theme.silvertail, + org.zkoss.theme.userdark, org.zkoss.util, org.zkoss.util.logging, org.zkoss.util.media, @@ -515,6 +517,8 @@ Export-Package: bsh, org.zkoss.zuti.bind, org.zkoss.zuti.zul, web, + web.WEB-INF.tld.web, + web.WEB-INF.tld.zk, web.aud, web.dsp.action.html, web.html, @@ -825,8 +829,6 @@ Export-Package: bsh, web.zul.img.tree, web.zul.img.wnd, web.zul.less, - web.zul.less.font, - web.WEB-INF.tld.web, - web.WEB-INF.tld.zk + web.zul.less.font Require-Bundle: javax.servlet-api;bundle-version="3.1.0" Import-Package: org.slf4j;version="1.7.2" diff --git a/server/user.commons.zk/build.properties b/server/user.commons.zk/build.properties index 4faffaf1..7796f699 100644 --- a/server/user.commons.zk/build.properties +++ b/server/user.commons.zk/build.properties @@ -43,4 +43,5 @@ bin.includes = META-INF/,\ lib/zul.jar,\ lib/zuti.jar,\ lib/zweb.jar,\ - lib/datahandler-syntax-highlight-1.0.0.jar + lib/datahandler-syntax-highlight-1.0.0.jar,\ + lib/userdark-8.0.3.jar diff --git a/server/user.commons.zk/lib/userdark-8.0.3.jar b/server/user.commons.zk/lib/userdark-8.0.3.jar new file mode 100644 index 00000000..0e1464b6 Binary files /dev/null and b/server/user.commons.zk/lib/userdark-8.0.3.jar differ diff --git a/server/user.commons.zk/pom.xml b/server/user.commons.zk/pom.xml index 40de24e7..944ecb30 100644 --- a/server/user.commons.zk/pom.xml +++ b/server/user.commons.zk/pom.xml @@ -11,4 +11,34 @@ user.commons.zk eclipse-plugin 8.0.3 + + + + org.apache.maven.plugins + maven-resources-plugin + 2.7 + + + copy-jar + install + + copy-resources + + + ${project.basedir}/../-product/target/deploy + + + target + + ${project.artifactId}_${project.version}.jar + + + + UTF-8 + + + + + + \ No newline at end of file diff --git a/server/user.jobengine.executors/src/user/jobengine/server/steps/SyncOCTOPUSDataStep.java b/server/user.jobengine.executors/src/user/jobengine/server/steps/SyncOCTOPUSDataStep.java index 2560cfb5..98136041 100644 --- a/server/user.jobengine.executors/src/user/jobengine/server/steps/SyncOCTOPUSDataStep.java +++ b/server/user.jobengine.executors/src/user/jobengine/server/steps/SyncOCTOPUSDataStep.java @@ -11,10 +11,10 @@ public class SyncOCTOPUSDataStep extends JobStep { private IProgressEventListener progressListener; @StepEntry - public Object[] execute(boolean includeArchived, String address, String user, String pwd) throws Exception { + public Object[] execute(boolean includeArchived, int maxPastDays, String address, String user, String pwd) throws Exception { OctopusDataMiner dataMiner = null; try { - dataMiner = new OctopusDataMiner(address, user, pwd); + dataMiner = new OctopusDataMiner(address, user, pwd, maxPastDays); dataMiner.addProgressListener(e -> { setProgress(e.getProgress()); }); diff --git a/server/user.jobengine.executors/src/user/jobengine/server/steps/shared/OctopusDataMiner.java b/server/user.jobengine.executors/src/user/jobengine/server/steps/shared/OctopusDataMiner.java index e01b4613..a49e4e7f 100644 --- a/server/user.jobengine.executors/src/user/jobengine/server/steps/shared/OctopusDataMiner.java +++ b/server/user.jobengine.executors/src/user/jobengine/server/steps/shared/OctopusDataMiner.java @@ -1,5 +1,8 @@ package user.jobengine.server.steps.shared; +import java.time.LocalDate; +import java.time.Period; +import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -42,6 +45,7 @@ public class OctopusDataMiner { private static final String MOS_ABSTRACT_END = ""; private static final Logger logger = LogManager.getLogger(); private static final String ARCHIVED = "archived"; + private static final String SCHEDULEDSTART = "scheduledStart"; private static final String FILTER = "filter"; private static final String LINEFEED = "\r\n"; private static final String SIMPLE_LINEFEED = "\n"; @@ -80,6 +84,7 @@ public class OctopusDataMiner { private int objectCount; private int currentObjectIndex; private boolean disableWrite = false; + private int maxPastDays; public OctopusDataMiner(String address, String user, String pwd) { db = NoSQLUtils.getNoSQLDB(); @@ -87,6 +92,11 @@ public class OctopusDataMiner { webTarget = client.target(address).register(new BasicAuthentication(user, pwd)); } + public OctopusDataMiner(String address, String user, String pwd, int maxPastDays) { + this(address, user, pwd); + this.maxPastDays = maxPastDays; + } + public void addProgressListener(IProgressEventListener listener) { if (progressListenerList == null) progressListenerList = new EventListenerList(); @@ -502,13 +512,33 @@ public class OctopusDataMiner { Response response = null; if (includeArchived) { response = query.post(Entity.entity(new BasicDBObject(FILTER, new BasicDBObject(ARCHIVED, true)).toString(), MediaType.APPLICATION_JSON)); - } else + } else { response = query.get(); + } String json = response.readEntity(String.class); BasicDBObject resultObject = getDbObject(json); if (resultObject != null) result = NoSQLUtils.asDBList(resultObject, RESULT); + + if (maxPastDays > 0 && result != null) { + logger.info("Using maxPastDays {} limit", maxPastDays); + List rundownList = NoSQLUtils.asList(result); + result = new BasicDBList(); + // "2022-12-02T19:10:00.000+01:00" + LocalDate oldestScheduleDate = LocalDate.now().minus(Period.ofDays(maxPastDays + 1)); + for (BasicDBObject rundown : rundownList) { + String scheduledStart = rundown.getString(SCHEDULEDSTART); + if (scheduledStart == null) + continue; + LocalDate scheduleDate = LocalDate.parse(scheduledStart, DateTimeFormatter.ISO_OFFSET_DATE_TIME); + if (scheduleDate.isAfter(oldestScheduleDate)) { + result.add(rundown); + } + + } + } + logger.trace(EXIT); return result; } diff --git a/server/user.jobengine.osgi.db/META-INF/MANIFEST.MF b/server/user.jobengine.osgi.db/META-INF/MANIFEST.MF index 74b2c8a0..13fe3c40 100644 --- a/server/user.jobengine.osgi.db/META-INF/MANIFEST.MF +++ b/server/user.jobengine.osgi.db/META-INF/MANIFEST.MF @@ -20,6 +20,7 @@ Import-Package: com.fasterxml.jackson.annotation;version="2.4.5", javax.ws.rs.client, javax.ws.rs.core, org.apache.commons.io;version="2.2.0", + org.apache.ibatis.jdbc;version="3.5.2", org.apache.logging.log4j, sqlj.runtime.ref Export-Package: user.jobengine.db, diff --git a/server/user.jobengine.osgi.db/src/user/jobengine/db/IItemManager.java b/server/user.jobengine.osgi.db/src/user/jobengine/db/IItemManager.java index 1a33ad4a..d32e41ee 100644 --- a/server/user.jobengine.osgi.db/src/user/jobengine/db/IItemManager.java +++ b/server/user.jobengine.osgi.db/src/user/jobengine/db/IItemManager.java @@ -46,8 +46,7 @@ public interface IItemManager extends IEntityPersister { */ void connect(); - FileType createFileType(String name, String description, String videoCodec, String audioCodec, int videoTracks, - int audioTracks, float frameRate); + FileType createFileType(String name, String description, String videoCodec, String audioCodec, int videoTracks, int audioTracks, float frameRate); Item createItem(String name, String description, String houseId); @@ -65,8 +64,8 @@ public interface IItemManager extends IEntityPersister { Metadata createMetadata(MetadataElement mde, ListType listType, GuiType guiType, MdType... flags); - Metadata createMetadata(MetadataElement mde, ListType listType, GuiType guiType, String sqlField, - StaticTables staticTable, String pojoField, MdType... flags); + Metadata createMetadata(MetadataElement mde, ListType listType, GuiType guiType, String sqlField, StaticTables staticTable, String pojoField, + MdType... flags); Metadata createMetadata(MetadataElement mde, MdType... flags); @@ -88,15 +87,15 @@ public interface IItemManager extends IEntityPersister { StoreUri createStoreUri(RemoteStoreProtocol protocol, String uri); - StoreUri createStoreUri(RemoteStoreProtocol protocol, String uri, int portNumber, boolean isStream, - boolean isSource, boolean isTarget, String userName, String password, String rootPath); + StoreUri createStoreUri(RemoteStoreProtocol protocol, String uri, int portNumber, boolean isStream, boolean isSource, boolean isTarget, String userName, + String password, String rootPath); StoreUri createStoreUri(URI uri); UserInfo createUser(String fullName, String userName, String password, UserRight[] rights); - WorkflowAction createWorkflowAction(Timestamp touched, Timestamp started, Timestamp finished, boolean successful, - String houseId, String description, String source, String destination, String tag, long size); + WorkflowAction createWorkflowAction(Timestamp touched, Timestamp started, Timestamp finished, boolean successful, String houseId, String description, + String source, String destination, String tag, long size); void disconnect(); @@ -106,8 +105,7 @@ public interface IItemManager extends IEntityPersister { boolean executeQuery(String query, IResultSetConsumer consumer, IStatementDecorator decorator); - int executeUpdate(Connection connection, String query, IStatementDecorator decorator, - IResultSetConsumer keysConsumer); + int executeUpdate(Connection connection, String query, IStatementDecorator decorator, IResultSetConsumer keysConsumer); // long getExistingRundownMedia(String houseid); @@ -465,4 +463,6 @@ public interface IItemManager extends IEntityPersister { * @param classInfo */ void truncate(Class classInfo); + + List getGroupChildren(ArchivedMedia master, String criteria); } \ No newline at end of file diff --git a/server/user.jobengine.osgi.db/src/user/jobengine/db/ItemManager.java b/server/user.jobengine.osgi.db/src/user/jobengine/db/ItemManager.java index 0641a583..4ca0eb2a 100644 --- a/server/user.jobengine.osgi.db/src/user/jobengine/db/ItemManager.java +++ b/server/user.jobengine.osgi.db/src/user/jobengine/db/ItemManager.java @@ -1315,6 +1315,15 @@ public class ItemManager extends MemoryCache implements IItemManager { return result; } + @Override + public List getGroupChildren(ArchivedMedia master, String criteria) { + traceIn(); + IMediaFinder finder = createFinder(); + List result = finder.getGroupChildren(master, criteria); + traceOut(); + return result; + } + @Override public List> searchItem(QueryObject parameter) { // traceIn(); diff --git a/server/user.jobengine.osgi.db/src/user/jobengine/db/SearchOptions.java b/server/user.jobengine.osgi.db/src/user/jobengine/db/SearchOptions.java index cf74a7a5..55ffa8d9 100644 --- a/server/user.jobengine.osgi.db/src/user/jobengine/db/SearchOptions.java +++ b/server/user.jobengine.osgi.db/src/user/jobengine/db/SearchOptions.java @@ -21,6 +21,7 @@ public class SearchOptions { private int fromResult; private int toResult; private boolean countOnly; + private boolean grouping; public StringBuilder getCriteriaForTag() { StringBuilder result = null; @@ -183,4 +184,13 @@ public class SearchOptions { this.countOnly = countOnly; } + public boolean isGrouping() { + return grouping; + } + + public SearchOptions setGrouping(boolean grouping) { + this.grouping = grouping; + return this; + } + } diff --git a/server/user.jobengine.osgi.db/src/user/jobengine/search/IMediaFinder.java b/server/user.jobengine.osgi.db/src/user/jobengine/search/IMediaFinder.java index f2579122..e808962a 100644 --- a/server/user.jobengine.osgi.db/src/user/jobengine/search/IMediaFinder.java +++ b/server/user.jobengine.osgi.db/src/user/jobengine/search/IMediaFinder.java @@ -1,5 +1,7 @@ package user.jobengine.search; +import java.util.List; + import user.jobengine.db.ArchivedMedia; import user.jobengine.db.SearchOptions; @@ -7,4 +9,6 @@ public interface IMediaFinder { SearchResult search(SearchOptions options); + List getGroupChildren(ArchivedMedia master, String criteria); + } diff --git a/server/user.jobengine.osgi.db/src/user/jobengine/search/LuceneMediaFinder.java b/server/user.jobengine.osgi.db/src/user/jobengine/search/LuceneMediaFinder.java index 683372a8..ddd71715 100644 --- a/server/user.jobengine.osgi.db/src/user/jobengine/search/LuceneMediaFinder.java +++ b/server/user.jobengine.osgi.db/src/user/jobengine/search/LuceneMediaFinder.java @@ -1,5 +1,7 @@ package user.jobengine.search; +import java.util.List; + import user.jobengine.db.ArchivedMedia; import user.jobengine.db.SearchOptions; @@ -39,4 +41,10 @@ public class LuceneMediaFinder implements IMediaFinder { return ret; } + @Override + public List getGroupChildren(ArchivedMedia master, String criteria) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/server/user.jobengine.osgi.db/src/user/jobengine/search/MediaFinder.java b/server/user.jobengine.osgi.db/src/user/jobengine/search/MediaFinder.java index 4662bbc0..6caa1006 100644 --- a/server/user.jobengine.osgi.db/src/user/jobengine/search/MediaFinder.java +++ b/server/user.jobengine.osgi.db/src/user/jobengine/search/MediaFinder.java @@ -8,6 +8,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; +import org.apache.ibatis.jdbc.SQL; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -127,6 +128,118 @@ public class MediaFinder implements IMediaFinder { return st; } + private PreparedStatement createGroupingChildrenStatement(Connection connection, String fileName, String criteria) throws SQLException { + SQL sql = new SQL(); + sql.SELECT("vi.itemid", "vi.itemtitle", "vi.mediaid", "vi.mediatitle", "vi.mediaarchived archived", "vi.mediacreation creation", + "vi.mediacreated created", "vi.mediamodified modified", "vi.medialength length", "vi.mediaitemtypeid", "vi.mediaitemtypename", + "vi.mediahouseid", "vi.mediafilehouseid", "vf.mediafilecount"); + + sql.FROM("VW_ITEMS_WITH_PATH vi", "VW_MEDIAFILES vf"); + sql.WHERE("vf.mediaid = vi.mediaid"); + sql.AND(); + sql.WHERE(String.format("vi.mediarelativepath = '%s'", fileName)); + sql.ORDER_BY("vi.mediacreation DESC"); + String query = sql.toString(); + logger.info(query); + + return connection.prepareStatement(sql.toString(), ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); + } + + private PreparedStatement createGroupingStatement(Connection connection, String criteria, SearchOptions options) throws Exception { + boolean simpleSearch = manager.getSystemConfig().value("datasource.mediacube.simple-search", true); + String criteriasPattern = getCriteriasRegexPattern(criteria); + + SQL innerSql = new SQL(); + innerSql.SELECT("max(vi.mediaid)"); + innerSql.FROM("VW_ITEMS_WITH_PATH vi", "MEDIADESCRIPTION md"); + innerSql.WHERE("vi.mediafileid = md.mediafileid"); + + if (simpleSearch) { + // TODO ezen az agon nem jo!!!!! + String simpleTextCriteria = formatSimpleSearchValue(criteria); + if (simpleTextCriteria != null && simpleTextCriteria.trim().length() > 0) { + innerSql.AND(); + innerSql.WHERE("("); + innerSql.WHERE(String.format("%s LIKE '%%%s%%'", "vi.mediatitle", simpleTextCriteria)); + innerSql.OR(); + innerSql.WHERE(String.format("%s LIKE '%%%s%%'", "vi.itemtitle", simpleTextCriteria)); + innerSql.OR(); + innerSql.WHERE(String.format("%s LIKE '%%%s%%'", "vi.mediarelativepath", simpleTextCriteria)); + innerSql.WHERE(")"); + } + } else { + String textCriteria = formatSearchValue(criteria); + if (textCriteria != null && textCriteria.trim().length() > 0) { + innerSql.AND(); + innerSql.WHERE(String.format("CONTAINS(md.description, '%s') >= 1", textCriteria)); + } + } + innerSql.GROUP_BY("vi.mediarelativepath"); + + SQL mainSql = new SQL(); + if (options.isCountOnly()) + mainSql.SELECT("COUNT(1) AS NumberOfRecords"); + else + mainSql.SELECT("vi.itemid", "vi.itemtitle", "vi.mediaid", "vi.mediatitle", "vi.mediarelativepath", "vi.mediaarchived", "vi.mediacreation", + "vi.medialength", "vf.mediafilecount", + String.format("HIGHLIGHT(md.description, '', '', '%s') description", criteriasPattern)); + + mainSql.FROM("VW_ITEMS_WITH_PATH vi", "VW_MEDIAFILES vf", "MEDIADESCRIPTION md"); + mainSql.WHERE("vf.mediaid = vi.mediaid"); + mainSql.AND(); + mainSql.WHERE("vi.mediafileid = md.mediafileid"); + mainSql.AND(); + mainSql.WHERE(String.format("vi.mediaid IN (\r\n%s\r\n)", innerSql.toString())); + + StringBuilder criteriaForType = options.getCriteriaForType(); + if (criteriaForType != null) { + mainSql.AND(); + mainSql.WHERE(String.format("vi.mediaitemtypeid IN (%s)", criteriaForType.toString())); + } + + StringBuilder criteriaForTag = options.getCriteriaForTag(); + if (criteriaForTag != null) { + SQL tagSql = new SQL(); + tagSql.SELECT("mediaid"); + tagSql.FROM("MEDIATAGS"); + tagSql.WHERE(String.format("vi.mediaitemtypeid IN (%s)", criteriaForTag.toString())); + + mainSql.AND(); + mainSql.WHERE(String.format("vi.mediaid IN (%s)", tagSql.toString())); + } + + if (options.getFrom() != null) { + mainSql.AND(); + mainSql.WHERE(String.format("vi.mediacreation > '%s'", df.format(options.getFrom()))); + } + + if (options.getTo() != null) { + mainSql.AND(); + mainSql.WHERE(String.format("vi.mediacreation < '%s'", df.format(options.getTo()))); + } + + if (options.isMissingProxy()) { + mainSql.AND(); + mainSql.WHERE("vf.mediafilecount = 1"); + } + + if (options.getDescLength() > 0) { + mainSql.AND(); + mainSql.WHERE(String.format("LENGTH(vi.mediadescription) < %s", options.getDescLength())); + } + + if (!options.isCountOnly() && (options.getToResult() != 0)) { + mainSql.ORDER_BY("vi.mediacreation DESC"); + mainSql.LIMIT((options.getToResult() - options.getFromResult())); + mainSql.OFFSET(options.getFromResult()); + } + + String query = mainSql.toString(); + logger.info(query); + PreparedStatement st = connection.prepareStatement(query, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); + return st; + } + private String formatSearchValue(String value) { String[] specials = new String[] { ":", "?", "%", "(", ")" }; String result = value; @@ -165,7 +278,11 @@ public class MediaFinder implements IMediaFinder { logger.info("Checking size"); options.setCountOnly(true); // creating a query for checking resultset size - st = createStatement(connection, options.getText(), options); + + if (options.isGrouping()) + st = createGroupingStatement(connection, options.getText(), options); + else + st = createStatement(connection, options.getText(), options); rs = st.executeQuery(); if (rs.next()) { result = rs.getLong("NumberOfRecords"); @@ -209,21 +326,30 @@ public class MediaFinder implements IMediaFinder { try { options.setCountOnly(false); - st = createStatement(connection, options.getText(), options); + if (options.isGrouping()) + st = createGroupingStatement(connection, options.getText(), options); + else + st = createStatement(connection, options.getText(), options); rs = st.executeQuery(); List resultList = null; while (rs.next()) { - ArchivedMedia am = createArchiveMedia(rs); - if (resultList == null) + ArchivedMedia am = null; + if (options.isGrouping()) + am = createGroupedArchiveMedia(rs, searchResults); + else { + am = createArchiveMedia(rs); + am.setRelevant(rs.getString("description")); + } + + if (resultList == null) { resultList = new ArrayList<>(); + searchResults.setItems(resultList); + } resultList.add(am); - - am.setRelevant(rs.getString("description")); } logger.info("Query result processed"); - searchResults.setItems(resultList); connection.commit(); } catch (Exception e) { try { @@ -250,6 +376,37 @@ public class MediaFinder implements IMediaFinder { logger.info("getSearchResults execution time is {} s", (float) (end - start) / 1000); } + private String formatSimpleSearchValue(String value) { + String result = value; + if (value.endsWith("*")) + result = value.replace("*", ""); + result = result.trim(); + return result; + } + + private ArchivedMedia createGroupedArchiveMedia(ResultSet rs, SearchResult searchResult) throws SQLException { + Item item = new Item(); + item.setId(rs.getLong("itemid")); + item.setTitle(rs.getString("itemtitle")); + + Media media = new Media(); + media.setMediaFilesName(rs.getString("mediarelativepath")); + media.setId(rs.getLong("mediaid")); + media.setTitle(rs.getString("mediatitle")); + + media.setCreation(rs.getTimestamp("mediacreation")); + media.setArchived(rs.getTimestamp("mediaarchived")); + media.setLength(rs.getLong("medialength")); + media.setMediaFilesCount(rs.getInt("mediafilecount")); + + ArchivedMedia am = new ArchivedMedia(); + am.setMedia(media); + am.setItem(item); + am.setRelevant(rs.getString("description")); + return am; + + } + private ArchivedMedia createArchiveMedia(ResultSet rs) throws SQLException { ItemType it = new ItemType(); it.setId(rs.getLong("mediaitemtypeid")); @@ -297,4 +454,49 @@ public class MediaFinder implements IMediaFinder { return result; } + @Override + public List getGroupChildren(ArchivedMedia master, String criteria) { + ResultSet rs = null; + PreparedStatement st = null; + + DefaultContext context = manager.getDbContext(); + Connection connection = context.getConnection(); + + List resultList = null; + try { + st = createGroupingChildrenStatement(connection, master.getMedia().getMediaFilesName(), criteria); + rs = st.executeQuery(); + + while (rs.next()) { + + ArchivedMedia am = createArchiveMedia(rs); + if (resultList == null) + resultList = new ArrayList<>(); + resultList.add(am); + } + connection.commit(); + } catch (Exception e) { + try { + connection.rollback(); + } catch (Exception e1) { + logger.throwing(e1); + } + manager.throwError(e); + } finally { + try { + if (rs != null) + rs.close(); + } catch (Exception e1) { + } + try { + if (st != null) + st.close(); + } catch (Exception e1) { + } + + manager.putDbContext(context); + } + return resultList; + } + } diff --git a/server/user.jobengine.osgi.db/src/user/jobengine/search/SearchResult.java b/server/user.jobengine.osgi.db/src/user/jobengine/search/SearchResult.java index 4e34f4fd..34299a58 100644 --- a/server/user.jobengine.osgi.db/src/user/jobengine/search/SearchResult.java +++ b/server/user.jobengine.osgi.db/src/user/jobengine/search/SearchResult.java @@ -22,4 +22,5 @@ public class SearchResult { public void setItems(List items) { this.items = items; } + } \ No newline at end of file diff --git a/server/user.mediacube.gui/WEB-INF/zk.xml b/server/user.mediacube.gui/WEB-INF/zk.xml index 39f79d9d..054d39f7 100644 --- a/server/user.mediacube.gui/WEB-INF/zk.xml +++ b/server/user.mediacube.gui/WEB-INF/zk.xml @@ -7,6 +7,13 @@ https://www.zkoss.org/wiki/ZK_Configuration_Reference/zk.xml + + + org.zkoss.theme.preferred + userdark + + org.zkoss.web.preferred.locale hu diff --git a/server/user.mediacube.gui/css/archivum.css b/server/user.mediacube.gui/css/archivum.css index 8a40170a..b1e9fb05 100644 --- a/server/user.mediacube.gui/css/archivum.css +++ b/server/user.mediacube.gui/css/archivum.css @@ -240,25 +240,4 @@ body *:not([class*="z-icon-"]) { padding: 5px; } -/* -VideoJS controls never hide -https://player.support.brightcove.com/styling/customizing-player-appearance.html -https://www.endpointdev.com/blog/2016/03/creating-video-player-with-time-markers/ -*/ -/* .video-js.not-hover.vjs-has-started.vjs-paused.vjs-user-active .vjs-control-bar:not(.vjs-focus-within):not(.vjs-control-bar-visible), */ -/* .video-js.not-hover.vjs-has-started.vjs-paused.vjs-user-inactive .vjs-control-bar:not(.vjs-focus-within):not(.vjs-control-bar-visible), */ -/* .video-js.not-hover.vjs-has-started.vjs-playing.vjs-user-active .vjs-control-bar:not(.vjs-focus-within):not(.vjs-control-bar-visible), */ -/* .video-js.not-hover.vjs-has-started.vjs-playing.vjs-user-inactive .vjs-control-bar:not(.vjs-focus-within):not(.vjs-control-bar-visible), */ -/* .video-js.vjs-has-started.vjs-paused.vjs-ad-playing.vjs-user-inactive .vjs-control-bar, */ -/* .video-js.vjs-has-started.vjs-playing.vjs-user-inactive .vjs-control-bar:not(.vjs-focus-within):not(.vjs-control-bar-visible){ */ -/* transform: none; */ -/* -webkit-transform: none; */ -/* -ms-transform: none; */ -/* } */ - -.video-js .vjs-time-control { - display: block; -} -/* .video-js .vjs-remaining-time { */ -/* display: none; */ -/* } */ + \ No newline at end of file diff --git a/server/user.mediacube.gui/css/searchitems.css b/server/user.mediacube.gui/css/searchitems.css index 4c7832aa..880fae40 100644 --- a/server/user.mediacube.gui/css/searchitems.css +++ b/server/user.mediacube.gui/css/searchitems.css @@ -221,6 +221,31 @@ LIST background: #F1F8E9; } + + +/* +VideoJS controls never hide +https://player.support.brightcove.com/styling/customizing-player-appearance.html +https://www.endpointdev.com/blog/2016/03/creating-video-player-with-time-markers/ +*/ +/* .video-js.not-hover.vjs-has-started.vjs-paused.vjs-user-active .vjs-control-bar:not(.vjs-focus-within):not(.vjs-control-bar-visible), */ +/* .video-js.not-hover.vjs-has-started.vjs-paused.vjs-user-inactive .vjs-control-bar:not(.vjs-focus-within):not(.vjs-control-bar-visible), */ +/* .video-js.not-hover.vjs-has-started.vjs-playing.vjs-user-active .vjs-control-bar:not(.vjs-focus-within):not(.vjs-control-bar-visible), */ +/* .video-js.not-hover.vjs-has-started.vjs-playing.vjs-user-inactive .vjs-control-bar:not(.vjs-focus-within):not(.vjs-control-bar-visible), */ +/* .video-js.vjs-has-started.vjs-paused.vjs-ad-playing.vjs-user-inactive .vjs-control-bar, */ +/* .video-js.vjs-has-started.vjs-playing.vjs-user-inactive .vjs-control-bar:not(.vjs-focus-within):not(.vjs-control-bar-visible){ */ +/* transform: none; */ +/* -webkit-transform: none; */ +/* -ms-transform: none; */ +/* } */ + +.video-js .vjs-time-control { + display: block; +} +/* .video-js .vjs-remaining-time { */ +/* display: none; */ +/* } */ + .video-js .vjs-remaining-time, .vjs-no-flex .vjs-remaining-time { display: none; @@ -271,4 +296,5 @@ LIST font-family: Arial, Helvetica, sans-serif; overflow: auto; z-index: 2; -} \ No newline at end of file +} + diff --git a/server/user.mediacube.gui/index.zul b/server/user.mediacube.gui/index.zul index 821c540d..76205d89 100644 --- a/server/user.mediacube.gui/index.zul +++ b/server/user.mediacube.gui/index.zul @@ -6,7 +6,7 @@ - + border="normal" hflex="min" > @@ -34,8 +42,8 @@ -