diff --git a/current/core/pom.xml b/current/core/pom.xml index d82bb4f..bfa98be 100644 --- a/current/core/pom.xml +++ b/current/core/pom.xml @@ -46,7 +46,7 @@ com.coresecure.brightcove.cq5 brightcove_connector - 6.0.0 + 6.0.2 ../pom.xml brightcove-services diff --git a/current/core/src/main/java/com/coresecure/brightcove/wrapper/api/CmsAPI.java b/current/core/src/main/java/com/coresecure/brightcove/wrapper/api/CmsAPI.java index a668543..d9b6a9f 100644 --- a/current/core/src/main/java/com/coresecure/brightcove/wrapper/api/CmsAPI.java +++ b/current/core/src/main/java/com/coresecure/brightcove/wrapper/api/CmsAPI.java @@ -323,6 +323,34 @@ public JSONObject updatePlaylist(String playlistId, String[] videos) { return json; } + public JSONObject updateLabels(String videoId, String[] labels) { + JSONObject json = new JSONObject(); + TokenObj authToken = account.getLoginToken(); + if (authToken != null) { + Map headers = new HashMap(); + headers.put(Constants.AUTHENTICATION_HEADER, authToken.getTokenType() + " " + authToken.getToken()); + String targetURL = Constants.ACCOUNTS_API_PATH + account.getAccount_ID() + "/videos" + + "/" + videoId; + try { + LOGGER.debug("targetURL: {}", targetURL); + JSONObject request = new JSONObject(); + ArrayList labelArray = new ArrayList(); + for (String item : labels) { + labelArray.add(item); + } + request.put("labels", new JSONArray(labelArray)); + LOGGER.info("updateVideoParams: {}", request.toString(1)); + String response = account.platform.patchAPI(targetURL, request.toString(1), headers); + if (response != null && !response.isEmpty()) json = JsonReader.readJsonFromString(response); + } catch (IOException e) { + LOGGER.error(e.getClass().getName(), e); + } catch (JSONException e) { + LOGGER.error(e.getClass().getName(), e); + } + } + return json; + } + //deleteAPI public JSONObject deleteVideo(String videoID) { JSONObject json = new JSONObject(); @@ -407,6 +435,29 @@ public JSONObject createPlaylist(Playlist aPlaylist) { return json; } + public JSONObject createLabel(String label) { + JSONObject json = new JSONObject(); + TokenObj authToken = account.getLoginToken(); + if (authToken != null) + { + Map headers = new HashMap(); + headers.put(Constants.AUTHENTICATION_HEADER, authToken.getTokenType() + " " + authToken.getToken()); + String targetURL = Constants.ACCOUNTS_API_PATH + account.getAccount_ID() + "/labels"; + try { + LOGGER.debug("Label {}", label.toString()); + String response = account.platform.postAPI(targetURL, "{ \"path\": \"" + label + "\" }", headers); + if (response != null && !response.isEmpty()) json = JsonReader.readJsonFromString(response); + } catch (IOException e) { + LOGGER.error(e.getClass().getName(), e); + } catch (JSONException e) + { + LOGGER.error(e.getClass().getName(), e); + } + } + LOGGER.trace("createLabel: {} Response: {}", label, json); + return json; + } + public JSONObject getVideosCount(String q) { return getVideosCount(q, true); } diff --git a/current/core/src/main/java/com/coresecure/brightcove/wrapper/objects/Folder.java b/current/core/src/main/java/com/coresecure/brightcove/wrapper/objects/Folder.java new file mode 100644 index 0000000..ccd23c1 --- /dev/null +++ b/current/core/src/main/java/com/coresecure/brightcove/wrapper/objects/Folder.java @@ -0,0 +1,79 @@ +/* + + Adobe AEM Brightcove Connector + + Copyright (C) 2018 Coresecure Inc. + + Authors: Alessandro Bonfatti + Yan Kisen + Pablo Kropilnicki + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + - Additional permission under GNU GPL version 3 section 7 + If you modify this Program, or any covered work, by linking or combining + it with httpclient 4.1.3, httpcore 4.1.4, httpmine 4.1.3, jsoup 1.7.2, + squeakysand-commons and squeakysand-osgi (or a modified version of those + libraries), containing parts covered by the terms of APACHE LICENSE 2.0 + or MIT License, the licensors of this Program grant you additional + permission to convey the resulting work. + + */ +package com.coresecure.brightcove.wrapper.objects; + +import com.coresecure.brightcove.wrapper.enums.GeoFilterCodeEnum; +import com.coresecure.brightcove.wrapper.utils.Constants; +import com.coresecure.brightcove.wrapper.utils.ObjectSerializer; +import org.apache.sling.commons.json.JSONException; +import org.apache.sling.commons.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collection; + +public class Folder { + public final String id; + public final String name; + public final String path; + private static final Logger LOGGER = LoggerFactory.getLogger(Folder.class); + + public Folder(String aId, String aName, String aPath) { + id = aId; + name = aName; + path = aPath; + } + + public Folder(JSONObject aFolder) throws JSONException { + id = aFolder.getString(Constants.ID); + name = aFolder.getString(Constants.FOLDER_ID); + path = ""; + } + + public JSONObject toJSON() throws JSONException { + JSONObject json = ObjectSerializer.toJSON(this, new String[]{Constants.ID, Constants.NAME}); + return json; + } + + public String toString() { + String result = new String(); + try { + result = toJSON().toString(); + } catch (JSONException e) { + LOGGER.error(e.getClass().getName(),e); + } + return result; + } + +} diff --git a/current/core/src/main/java/com/coresecure/brightcove/wrapper/objects/Video.java b/current/core/src/main/java/com/coresecure/brightcove/wrapper/objects/Video.java index 353b998..218d153 100644 --- a/current/core/src/main/java/com/coresecure/brightcove/wrapper/objects/Video.java +++ b/current/core/src/main/java/com/coresecure/brightcove/wrapper/objects/Video.java @@ -55,6 +55,7 @@ public class Video { public final String reference_id; public final String description; public final String long_description; + public final String folderId; public final String state; public final Collection tags; public final Collection labels; @@ -65,6 +66,7 @@ public class Video { public final boolean complete; public final EconomicsEnum economics; public final JSONArray text_tracks; + public final JSONArray variants; public final Images images; @@ -94,10 +96,18 @@ public Video(String aId, String aName, String aReference_id, String aDescription } public Video(String aId, String aName, String aReference_id, String aDescription, String aLong_description, String aState, Collection aTags, Geo aGeo, Schedule aSchedule, boolean aComplete, RelatedLink aLink, Map aCustom_fields, EconomicsEnum aEconomics, String aProjection, JSONArray aText_tracks, Images aImages) { - this(aId, aName, aReference_id, aDescription, aLong_description, aState, aTags, aGeo, aSchedule, aComplete, aLink, aCustom_fields, aEconomics, aProjection, aText_tracks, aImages, null, null); + this(aId, aName, aReference_id, aDescription, aLong_description, aState, aTags, aGeo, aSchedule, aComplete, aLink, aCustom_fields, aEconomics, aProjection, aText_tracks, aImages, null, null, null, null); } - private Video(String aId, String aName, String aReference_id, String aDescription, String aLong_description, String aState, Collection aTags, Geo aGeo, Schedule aSchedule, boolean aComplete, RelatedLink aLink, Map aCustom_fields, EconomicsEnum aEconomics, String aProjection, JSONArray aText_tracks, Images aImages, String aAccountId, Collection aLabels) { + public Video(String aId, String aName, String aReference_id, String aDescription, String aLong_description, String aState, Collection aTags, Geo aGeo, Schedule aSchedule, boolean aComplete, RelatedLink aLink, Map aCustom_fields, EconomicsEnum aEconomics, String aProjection, JSONArray aText_tracks, Images aImages, Collection aLabels) { + this(aId, aName, aReference_id, aDescription, aLong_description, aState, aTags, aGeo, aSchedule, aComplete, aLink, aCustom_fields, aEconomics, aProjection, aText_tracks, aImages, null, aLabels, null, null); + } + + public Video(String aId, String aName, String aReference_id, String aDescription, String aLong_description, String aState, Collection aTags, Geo aGeo, Schedule aSchedule, boolean aComplete, RelatedLink aLink, Map aCustom_fields, EconomicsEnum aEconomics, String aProjection, JSONArray aText_tracks, Images aImages, Collection aLabels, JSONArray aVariants) { + this(aId, aName, aReference_id, aDescription, aLong_description, aState, aTags, aGeo, aSchedule, aComplete, aLink, aCustom_fields, aEconomics, aProjection, aText_tracks, aImages, null, aLabels, aVariants, null); + } + + private Video(String aId, String aName, String aReference_id, String aDescription, String aLong_description, String aState, Collection aTags, Geo aGeo, Schedule aSchedule, boolean aComplete, RelatedLink aLink, Map aCustom_fields, EconomicsEnum aEconomics, String aProjection, JSONArray aText_tracks, Images aImages, String aAccountId, Collection aLabels, JSONArray aVariants, String aFolderId) { id = aId; account_id = aAccountId; name = aName; @@ -106,7 +116,6 @@ private Video(String aId, String aName, String aReference_id, String aDescriptio long_description = aLong_description; state = aState; tags = aTags; - labels = aLabels; geo = aGeo; schedule = aSchedule; link = aLink; @@ -115,7 +124,10 @@ private Video(String aId, String aName, String aReference_id, String aDescriptio economics = aEconomics; projection = new Projection(aProjection); text_tracks = aText_tracks; + variants = aVariants; images = aImages; + labels = aLabels; + folderId = aFolderId; } private Object getNotNull(JSONObject video, String key) throws JSONException{ @@ -129,6 +141,7 @@ public Video(JSONObject video) throws JSONException { Projection localprojection = null; String localreference_id = null; String localdescription = null; + String localfolderid = null; String locallong_description = null; String localstate = null; Collection localtags = null; @@ -140,6 +153,7 @@ public Video(JSONObject video) throws JSONException { boolean localcomplete = false; EconomicsEnum localeconomics = null; JSONArray localtext_tracks = null; + JSONArray localvariants = null; Images localimages = null; try { localid = (String) getNotNull(video, Constants.ID); @@ -147,6 +161,7 @@ public Video(JSONObject video) throws JSONException { localname = (String) getNotNull(video, Constants.NAME); localreference_id = (String) getNotNull(video, Constants.REFERENCE_ID); localdescription = (String) getNotNull(video, Constants.DESCRIPTION); + localfolderid = (String) getNotNull(video, Constants.FOLDER_ID); locallong_description = (String) getNotNull(video, Constants.LONG_DESCRIPTION); localstate = (String) getNotNull(video, Constants.STATE); localprojection = (Projection) getNotNull(video, Constants.PROJECTION); @@ -154,6 +169,7 @@ public Video(JSONObject video) throws JSONException { localschedule = (Schedule) getNotNull(video, Constants.SCHEDULE); locallink = (RelatedLink) getNotNull(video, Constants.LINK); localtext_tracks = (JSONArray) getNotNull(video, Constants.TEXT_TRACKS); + localvariants = (JSONArray) getNotNull(video, Constants.VARIANTS); localcomplete = (Boolean) getNotNull(video, Constants.COMPLETE); if (!video.isNull(Constants.TAGS)) { @@ -184,6 +200,7 @@ public Video(JSONObject video) throws JSONException { this.projection = localprojection; this.reference_id = localreference_id; this.description = localdescription; + this.folderId = localfolderid; this.long_description = locallong_description; this.state = localstate; this.tags = localtags; @@ -195,6 +212,7 @@ public Video(JSONObject video) throws JSONException { this.complete = localcomplete; this.economics = localeconomics; this.text_tracks = localtext_tracks; + this.variants = localvariants; this.images = localimages; } } diff --git a/current/core/src/main/java/com/coresecure/brightcove/wrapper/schedulers/asset_integrator/callables/VideoImportCallable.java b/current/core/src/main/java/com/coresecure/brightcove/wrapper/schedulers/asset_integrator/callables/VideoImportCallable.java index 71d97a3..13f9c52 100644 --- a/current/core/src/main/java/com/coresecure/brightcove/wrapper/schedulers/asset_integrator/callables/VideoImportCallable.java +++ b/current/core/src/main/java/com/coresecure/brightcove/wrapper/schedulers/asset_integrator/callables/VideoImportCallable.java @@ -193,12 +193,22 @@ private Asset createAsset(String localpath, String id, String brightcove_filenam return newAsset; } - private String cleanPath(String confPath, String filename){ + private String cleanPath(String confPath, String filename) { return (confPath.endsWith("/") ? confPath : confPath.concat("/")).concat(requestedServiceAccount + "/").concat(filename); } + + private String cleanPath(String confPath, String filename, String folderId) { + String accountFolder = (confPath.endsWith("/") ? confPath : confPath.concat("/")).concat(requestedServiceAccount + "/"); + if (folderId == null || folderId.length() == 0) + return accountFolder.concat(filename); + else + return accountFolder.concat(folderId + "/").concat(filename); + } + private String cleanFilename(JSONObject innerObj) throws JSONException{ return innerObj.getString(Constants.ORIGINAL_FILENAME) != null ? innerObj.getString(Constants.ORIGINAL_FILENAME).replaceAll("%20", " ") : null; } + private Asset getAsset(String oldpath, String localpath ){ Resource resource = resourceResolver.getResource(oldpath); if(resource != null) { @@ -210,6 +220,7 @@ private Asset getAsset(String oldpath, String localpath ){ } return null; } + public String call(){ // Get the Service resource resolver try { @@ -229,7 +240,6 @@ public String call(){ LOGGER.trace(">>>>START>>>>> {} >> {}", id ,active); - //TODO: CHECK IF VIDEO COMING INTO DAM (1) IS ACTIVE (2) HAS AN ID + SRC IMAGE?? if (!active) { LOGGER.warn("VIDEO INITIALIZATION FAILED - NOT ACTIVE / NO ID - skipping: " + innerObj.toString(1)); if (resourceResolver != null) { @@ -241,17 +251,18 @@ public String call(){ String name = innerObj.getString(Constants.NAME); String brightcove_filename = id + ".mp4"; //BRIGHTCOVE FILE NAME IS ID + . MP4 <- String original_filename = cleanFilename(innerObj); + String brightcove_folder_id = (innerObj.isNull(Constants.FOLDER_ID) ? "" : innerObj.getString(Constants.FOLDER_ID)); - LOGGER.trace("SYNCING VIDEO>>[" + name + "\tSTATE:ACTIVE\tTO BE:" + original_filename + "]"); + LOGGER.trace("SYNCING VIDEO >> [" + name + "\tSTATE:ACTIVE\tTO BE:" + original_filename + "]"); + + LOGGER.trace("VIDEO HAS FOLDER ID >> [" + brightcove_folder_id + "]"); //INITIALIZING ASSET SEARCH // INITIALIZATION Asset newAsset = null; - //TODO: PRINTING DEBUGGER (ENABLE TO DEBUG) - //USNIG THE CONFIGURATION - BUILD THE DIRECTORY TO SEARCH FOR THE LOCAL ASSETS OR BUILD INTO - String localpath = cleanPath(confPath,brightcove_filename); - String oldpath = cleanPath(confPath,original_filename); + String localpath = cleanPath(confPath, brightcove_filename, brightcove_folder_id); + String oldpath = cleanPath(confPath, original_filename, brightcove_folder_id); LOGGER.trace("SEARCHING FOR LOCAL ASSET"); LOGGER.trace(">>ORIGINAL: " + oldpath); @@ -286,10 +297,8 @@ public String call(){ } - } - LOGGER.trace(">>>>>>>>>{" + id + "}>>>>>END>>>>"); //MAIN VIDEO ARRAY TRAVERSAL LOOP diff --git a/current/core/src/main/java/com/coresecure/brightcove/wrapper/schedulers/asset_integrator/runnables/AssetPropertyIntegratorRunnable.java b/current/core/src/main/java/com/coresecure/brightcove/wrapper/schedulers/asset_integrator/runnables/AssetPropertyIntegratorRunnable.java index ae67724..3840052 100755 --- a/current/core/src/main/java/com/coresecure/brightcove/wrapper/schedulers/asset_integrator/runnables/AssetPropertyIntegratorRunnable.java +++ b/current/core/src/main/java/com/coresecure/brightcove/wrapper/schedulers/asset_integrator/runnables/AssetPropertyIntegratorRunnable.java @@ -41,15 +41,22 @@ import com.coresecure.brightcove.wrapper.sling.ServiceUtil; import com.coresecure.brightcove.wrapper.utils.Constants; import com.day.cq.commons.jcr.JcrUtil; + +import org.apache.jackrabbit.oak.jcr.Jcr; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceResolverFactory; import org.apache.sling.commons.json.JSONArray; +import org.apache.sling.commons.json.JSONException; import org.apache.sling.commons.json.JSONObject; import org.apache.sling.commons.mime.MimeTypeService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; +import javax.jcr.query.QueryResult; import javax.jcr.Node; +import javax.jcr.NodeIterator; import javax.jcr.Session; import java.util.*; import java.util.concurrent.Callable; @@ -117,6 +124,59 @@ public void run() session.save(); final ServiceUtil serviceUtil = new ServiceUtil(requestedAccount); + JSONArray folders = serviceUtil.getFoldersAsJsonArray(); + LOGGER.trace("<<< " + basePath + " USED AS BASE PATH!"); + LOGGER.trace("<<< " + folders.length() + " FOLDERS FOUND IN ACCOUNT: " + requestedAccount); + + if (folders.length() > 0) { + for (int x = 0; x < folders.length(); x++) { + JSONObject folder = folders.getJSONObject(x); + String folderId = folder.getString("id"); + String folderName = folder.getString("name"); + + String localFolderName = folderName.replaceAll(" ", "_").toLowerCase(); + + // check if folder (1) already exists or (2) has been renamed + QueryManager qm = session.getWorkspace().getQueryManager(); + String query = "SELECT * FROM [sling:OrderedFolder] AS node " + + "WHERE ISDESCENDANTNODE(node, \"" + basePath +"\") " + + "AND CONTAINS([brc_folder_id], \"" + folderId + "\")"; + Query q = qm.createQuery(query, Query.JCR_SQL2); + QueryResult result = q.execute(); + NodeIterator results = result.getNodes(); + + if (results.hasNext()) { + + // folder exists so update the title if it has been renamed + Node existingFolder = results.nextNode(); + existingFolder.setProperty("jcr:title", folderName); + LOGGER.trace("<<< " + existingFolder.getPath() + " EXISTING FOLDER FOUND!"); + + // we don't need to move if we use the folderId as the node path! + // if (!existingFolder.getPath().endsWith(localFolderName)) { + // // the folder has been renamed + // LOGGER.trace("<<< " + existingFolder + " compared to " + localFolderName); + // LOGGER.trace("<<< " + folderName + " HAS BEEN RENAMED AND MUST BE MOVED!"); + // session.move(existingFolder.getPath(), basePath + localFolderName); + // } + + } else { + + // folder does not exist so we need to create it + Node folderNode = JcrUtil.createPath(basePath + folderId, + "sling:OrderedFolder", session); + folderNode.setProperty("jcr:title", folderName); + folderNode.setProperty("brc_folder_id", folderId); + + LOGGER.trace("<<< " + folderNode.getPath() + " NEW FOLDER CREATED!"); + + } + + // save everything to the repository + session.save(); + } + } + //GET VIDEOS int startOffset = 0; JSONObject jsonObject = new JSONObject(serviceUtil.searchVideo("", startOffset, 0, Constants.NAME, true)); //QUERY<------ diff --git a/current/core/src/main/java/com/coresecure/brightcove/wrapper/sling/ServiceUtil.java b/current/core/src/main/java/com/coresecure/brightcove/wrapper/sling/ServiceUtil.java index af90480..230314f 100644 --- a/current/core/src/main/java/com/coresecure/brightcove/wrapper/sling/ServiceUtil.java +++ b/current/core/src/main/java/com/coresecure/brightcove/wrapper/sling/ServiceUtil.java @@ -74,7 +74,7 @@ public class ServiceUtil { private static final Logger LOGGER = LoggerFactory.getLogger(ServiceUtil.class); private static final String ISO_8601_24H_FULL_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; - private static final String[] fields = {Constants.NAME, Constants.CREATED_AT , Constants.DURATION, Constants.COMPLETE, Constants.ID, Constants.ACCOUNT_ID ,Constants.DESCRIPTION , Constants.LINK, Constants.TAGS, Constants.LONG_DESCRIPTION, Constants.REFERENCE_ID, Constants.ECONOMICS, Constants.UPDATED_AT , Constants.SCHEDULE, Constants.STATE, Constants.GEO , Constants.CUSTOM_FIELDS, Constants.TEXT_TRACKS , Constants.IMAGES ,Constants.PROJECTION, Constants.LABELS}; + private static final String[] fields = {Constants.NAME, Constants.CREATED_AT , Constants.DURATION, Constants.COMPLETE, Constants.ID, Constants.ACCOUNT_ID ,Constants.DESCRIPTION , Constants.LINK, Constants.TAGS, Constants.LONG_DESCRIPTION, Constants.REFERENCE_ID, Constants.ECONOMICS, Constants.UPDATED_AT , Constants.SCHEDULE, Constants.STATE, Constants.GEO , Constants.CUSTOM_FIELDS, Constants.TEXT_TRACKS , Constants.IMAGES ,Constants.PROJECTION, Constants.LABELS, Constants.VARIANTS}; private String account_id; public static final int DEFAULT_LIMIT = 100; @@ -419,6 +419,15 @@ public String getVideosWithLabel(String label, int offset) { return result; } + public JSONArray getFoldersAsJsonArray() { + try { + return brAPI.cms.getFolders(100, 0); + } catch (Exception e) { + LOGGER.error(e.getClass().getName(), e); + return null; + } + } + public String getFolders() { JSONObject items = new JSONObject(); String result = ""; @@ -999,6 +1008,8 @@ public void updateAsset(@Nonnull Asset newAsset, JSONObject innerObj, ResourceRe break; } + // set the sync time + map.put(Constants.BRC_LASTSYNC, com.coresecure.brightcove.wrapper.utils.JcrUtil.now2calendar()); String key = getKey(x); @@ -1039,9 +1050,6 @@ else if (x.equals(Constants.LINK)) { } } - //AFTER SETTING ALL THE METADATA - SET THE LAST UPDATE TIME - //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); - map.put(Constants.BRC_LASTSYNC, com.coresecure.brightcove.wrapper.utils.JcrUtil.now2calendar()); resourceResolver.commit(); LOGGER.trace(">>UPDATED METADATA FOR VIDEO : [{}]",map.get(Constants.BRC_ID)); @@ -1256,6 +1264,13 @@ public Video createVideo(String request, Asset asset, String aState) Collection tags = JcrUtil.tagsToCollection(tagsList); list = null; + String[] rawList = metadataRes.getValueMap().get(getKey(Constants.LABELS),new String[]{}); + List labelList = new ArrayList(Arrays.asList(rawList)); + rawList = labelList.toArray(new String[0]); + //REMOVE BRIGHTCOVE TAG BEFORE PUSH + Collection labels = JcrUtil.tagsToCollection(rawList); + labelList = null; + //STO FROM LOCAL VIDEOS INITIALIZE THESE SO THAT YOU CAN SEND -- COULD COME FROM PROPERTIES VALUE MAP String name = map.get(DamConstants.DC_TITLE, asset.getName()); diff --git a/current/core/src/main/java/com/coresecure/brightcove/wrapper/utils/Constants.java b/current/core/src/main/java/com/coresecure/brightcove/wrapper/utils/Constants.java index ebd8766..ac5a2b6 100644 --- a/current/core/src/main/java/com/coresecure/brightcove/wrapper/utils/Constants.java +++ b/current/core/src/main/java/com/coresecure/brightcove/wrapper/utils/Constants.java @@ -29,6 +29,7 @@ public Constants(){/* default implementation ignored */} public static final String LONG_DESCRIPTION = "long_description"; public static final String STATE = "state"; public static final String PROJECTION = "projection"; + public static final String VARIANTS = "variants"; public static final String TAGS = "tags"; public static final String LABELS = "labels"; diff --git a/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/AssetPropertyIntegrator.java b/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/AssetPropertyIntegrator.java index 94fec57..d25af6d 100755 --- a/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/AssetPropertyIntegrator.java +++ b/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/AssetPropertyIntegrator.java @@ -41,6 +41,8 @@ import com.coresecure.brightcove.wrapper.sling.ConfigurationService; import com.coresecure.brightcove.wrapper.sling.ServiceUtil; import com.day.cq.commons.jcr.JcrUtil; +import com.day.crx.JcrConstants; + import org.apache.felix.scr.annotations.*; import org.apache.felix.scr.annotations.Properties; import org.apache.sling.api.SlingHttpServletRequest; @@ -55,7 +57,12 @@ import org.slf4j.LoggerFactory; import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; +import javax.jcr.query.QueryResult; import javax.servlet.ServletException; import java.io.IOException; import java.util.*; @@ -129,6 +136,59 @@ private void executeRequest(final SlingHttpServletRequest req, final SlingHttpSe session.save(); final ServiceUtil serviceUtil = new ServiceUtil(requestedAccount); + JSONArray folders = serviceUtil.getFoldersAsJsonArray(); + LOGGER.trace("<<< " + basePath + " USED AS BASE PATH!"); + LOGGER.trace("<<< " + folders.length() + " FOLDERS FOUND IN ACCOUNT: " + requestedAccount); + + if (folders.length() > 0) { + for (int x = 0; x < folders.length(); x++) { + JSONObject folder = folders.getJSONObject(x); + String folderId = folder.getString("id"); + String folderName = folder.getString("name"); + + String localFolderName = folderName.replaceAll(" ", "_").toLowerCase(); + + // check if folder (1) already exists or (2) has been renamed + QueryManager qm = session.getWorkspace().getQueryManager(); + String query = "SELECT * FROM [sling:OrderedFolder] AS node " + + "WHERE ISDESCENDANTNODE(node, \"" + basePath +"\") " + + "AND CONTAINS([brc_folder_id], \"" + folderId + "\")"; + Query q = qm.createQuery(query, Query.JCR_SQL2); + QueryResult result = q.execute(); + NodeIterator results = result.getNodes(); + + if (results.hasNext()) { + + // folder exists so update the title if it has been renamed + Node existingFolder = results.nextNode(); + existingFolder.setProperty("jcr:title", folderName); + LOGGER.trace("<<< " + existingFolder.getPath() + " EXISTING FOLDER FOUND!"); + + // we don't need to move if we use the folderId as the node path! + // if (!existingFolder.getPath().endsWith(localFolderName)) { + // // the folder has been renamed + // LOGGER.trace("<<< " + existingFolder + " compared to " + localFolderName); + // LOGGER.trace("<<< " + folderName + " HAS BEEN RENAMED AND MUST BE MOVED!"); + // session.move(existingFolder.getPath(), basePath + localFolderName); + // } + + } else { + + // folder does not exist so we need to create it + Node folderNode = JcrUtil.createPath(basePath + folderId, + "sling:OrderedFolder", session); + folderNode.setProperty("jcr:title", folderName); + folderNode.setProperty("brc_folder_id", folderId); + + LOGGER.trace("<<< " + folderNode.getPath() + " NEW FOLDER CREATED!"); + + } + + // save everything to the repository + session.save(); + } + } + //GET VIDEOS int startOffset = 0; JSONObject jsonObject = new JSONObject(serviceUtil.searchVideo("", startOffset, 0)); //QUERY<------ diff --git a/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcApi.java b/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcApi.java index 8b9850f..ba65c4d 100755 --- a/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcApi.java +++ b/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcApi.java @@ -343,6 +343,26 @@ private JSONObject createPlaylist(SlingHttpServletRequest request) throws JSONEx return result; } + private JSONObject createLabel(SlingHttpServletRequest request) throws JSONException { + JSONObject result = new JSONObject(); + RequestParameter requestParameter = request.getRequestParameter(Constants.LABEL); + + if (requestParameter == null) { + result.put(Constants.ERROR, 500); + return result; + } + + LOGGER.info("Creating a Label"); + JSONObject labelResult = brAPI.cms.createLabel(requestParameter.toString()); + + if (!labelResult.has(Constants.ID)) { + result.put(Constants.ERROR, 409); + } else { + result = null; + } + return result; + } + private JSONObject createVideo(SlingHttpServletRequest request) throws JSONException { JSONObject result = new JSONObject(); RequestParameter requestParameter = request.getRequestParameter(Constants.PLST); @@ -443,6 +463,16 @@ private JSONObject updatePlaylist(SlingHttpServletRequest request) throws JSONEx return result; } + private JSONObject updateLabels(SlingHttpServletRequest request) throws JSONException { + JSONObject result = new JSONObject(); + if ( (request.getParameter("labels") != null) && (request.getParameter("videoId") != null) ) { + String[] labels = request.getParameterValues("labels"); + String videoId = request.getParameter("videoId"); + result = brAPI.cms.updateLabels(videoId, labels); + } + return result; + } + private JSONObject removeTextTrack(SlingHttpServletRequest request) throws JSONException { try { String trackID = request.getParameter("track"); @@ -646,8 +676,12 @@ private JSONObject apiLogic(SlingHttpServletRequest request, SlingHttpServletRes result = getVideosInPlayList(request); } else if ("update_playlist".equals(requestedAPI)) { result = updatePlaylist(request); + } else if ("update_labels".equals(requestedAPI)) { + result = updateLabels(request); } else if ("list_labels".equals(requestedAPI)) { result = getLabels(request); + } else if ("create_label".equals(requestedAPI)) { + result = createLabel(request); } else { result.put(Constants.ERROR, 404); } diff --git a/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcImageApi.java b/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcImageApi.java index 757973a..d8afd7d 100755 --- a/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcImageApi.java +++ b/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcImageApi.java @@ -73,9 +73,6 @@ private String getPoster(String accountKeyStr, String VideoIDStr) throws JSONExc JSONObject video = brAPI.cms.getVideoImages(VideoIDStr); - - //TODO: MODULARIZE - // Find a single video if (video != null && video.has(Constants.POSTER)) { JSONObject poster = video.getJSONObject(Constants.POSTER); diff --git a/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcReplicationHandler.java b/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcReplicationHandler.java index 4ee346a..d83dadc 100644 --- a/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcReplicationHandler.java +++ b/current/core/src/main/java/com/coresecure/brightcove/wrapper/webservices/BrcReplicationHandler.java @@ -52,6 +52,7 @@ import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; +import javax.jcr.Node; import javax.jcr.RepositoryException; import java.io.InputStream; import java.util.*; @@ -180,7 +181,15 @@ private ReplicationResult replicateAssets(ResourceResolver rr, String current_pa if (parent == null) { return result; } - String account_id = parent.getName(); + // update this to make sure we grab the right parent now that we have subfolders + String account_id; + Node parentNode = parent.adaptTo(Node.class); + if (parentNode.hasProperty("brc_folder_id")) { + // this is not the actual account folder, so let's go up one more + account_id = parent.getParent().getName(); + } else { + account_id = parent.getName(); + } Asset _asset = asset_res.adaptTo(Asset.class); if (_asset == null){ LOGGER.warn("Asset removed or not existing"); @@ -374,6 +383,16 @@ private ReplicationResult activateNew(Asset _asset, ServiceUtil serviceUtil, Vid LOGGER.trace("UPDATING RENDITIONS FOR THIS ASSET"); serviceUtil.updateRenditions(_asset, video); + Node assetNode = _asset.adaptTo(Node.class); + LOGGER.trace("CHECKING PARENT FOR BRC_FOLDER_ID: " + assetNode.getParent().getPath()); + if (assetNode.getParent().hasProperty("brc_folder_id")) { + // this is in a subfolder so we need to formally move the asset to this folder + String brc_folder_id = assetNode.getParent().getProperty("brc_folder_id").getString(); + LOGGER.trace("SUBFOLDER FOUND - SETTING THE FOLDER ID to '" + brc_folder_id + "'"); + serviceUtil.moveVideoToFolder( + brc_folder_id, + api_resp.getString(Constants.VIDEOID)); + } replicationLog.info("BC: ACTIVATION SUCCESSFUL >> {}" , _asset.getPath()); result = ReplicationResult.OK; @@ -402,6 +421,17 @@ private ReplicationResult activateModified(Asset _asset, ServiceUtil serviceUtil LOGGER.trace("UPDATING RENDITIONS FOR THIS ASSET"); serviceUtil.updateRenditions(_asset, video); + Node assetNode = _asset.adaptTo(Node.class); + LOGGER.trace("CHECKING PARENT FOR BRC_FOLDER_ID: " + assetNode.getParent().getPath()); + if (assetNode.getParent().hasProperty("brc_folder_id")) { + // this is in a subfolder so we need to formally move the asset to this folder + String brc_folder_id = assetNode.getParent().getProperty("brc_folder_id").getString(); + LOGGER.trace("SUBFOLDER FOUND - SETTING THE FOLDER ID to '" + brc_folder_id + "'"); + serviceUtil.moveVideoToFolder( + brc_folder_id, + api_resp.getString(Constants.VIDEOID)); + } + replicationLog.info(Constants.REP_ACTIVATION_SUCCESS_TMPL, _asset.getPath()); long current_time_millisec = new Date().getTime(); brc_lastsync_map.put(Constants.BRC_LASTSYNC, current_time_millisec); diff --git a/current/core/src/test/java/com/coresecure/brightcove/wrapper/APITest.java b/current/core/src/test/java/com/coresecure/brightcove/wrapper/APITest.java index 7806a51..f2e3cf6 100644 --- a/current/core/src/test/java/com/coresecure/brightcove/wrapper/APITest.java +++ b/current/core/src/test/java/com/coresecure/brightcove/wrapper/APITest.java @@ -131,7 +131,6 @@ public void MainTest() { TestStaticStructures(); - //TEST INTEGRATION TEST//TODO: Not ready TestModelsAEM(); BundleActivatorTest(); @@ -572,7 +571,6 @@ private void ApiTest(CmsAPI api) { String q = ""; JSONArray input = new JSONArray(); - //TODO: Implemment this the right way - with a integration test video (requires research) JSONObject uploadInjestResponse = api.uploadInjest(payloadVideoID, payload); JSONObject requestIngestURLResponse = api.requestIngestURL(payloadVideoID, profile, master, false); JSONObject getIngestURLResponse = api.getIngestURL(payloadVideoID, filename); @@ -1279,8 +1277,8 @@ private void MockTests() { } - - + + } diff --git a/current/pom.xml b/current/pom.xml index 72afb74..ce4193f 100644 --- a/current/pom.xml +++ b/current/pom.xml @@ -45,7 +45,7 @@ Copyright (C) 2019 3|SHARE Inc. com.coresecure.brightcove.cq5 brightcove_connector pom - 6.0.0 + 6.0.2 Parent Maven POM for the 'Adobe CQ5 Brightcove Connector API' project. diff --git a/current/ui.apps/pom.xml b/current/ui.apps/pom.xml index e0898ed..ad5de72 100644 --- a/current/ui.apps/pom.xml +++ b/current/ui.apps/pom.xml @@ -49,7 +49,7 @@ com.coresecure.brightcove.cq5 brightcove_connector - 6.0.0 + 6.0.2 ../pom.xml @@ -227,7 +227,7 @@ com.coresecure.brightcove.cq5 brightcove-services - 6.0.0 + 6.0.2 diff --git a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/content/brightcoveplayer/player-embed.html b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/content/brightcoveplayer/player-embed.html index 42044ef..556ae5d 100644 --- a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/content/brightcoveplayer/player-embed.html +++ b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/content/brightcoveplayer/player-embed.html @@ -35,8 +35,8 @@ data-embed="${player.playerDataEmbed}" data-usage="cms:aem:${player.version}:${player.bundleVersion}:javascript" data-video-id="${player.videoID}" - data-width="${player.width}" - data-height="${player.height}"> + data-sly-attribute.data-width="${player.width ? player.width : ''}" + data-sly-attribute.data-height="${player.height ? player.height : ''}"> diff --git a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/page/brightcoveplayer/clientlib/.content.xml b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/page/brightcoveplayer/clientlib/.content.xml index dec9c70..6510b61 100644 --- a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/page/brightcoveplayer/clientlib/.content.xml +++ b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/page/brightcoveplayer/clientlib/.content.xml @@ -2,4 +2,4 @@ + dependencies="[lodash.underscore]"/> diff --git a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/shared/autoDialog/autoDialog.jsp b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/shared/autoDialog/autoDialog.jsp index 0905a44..d7c8740 100644 --- a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/shared/autoDialog/autoDialog.jsp +++ b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/shared/autoDialog/autoDialog.jsp @@ -44,7 +44,15 @@ ValueMap parentProps = asset_res.getParent().getValueMap(); if ( parentProps != null && parentProps.get("jcr:createdBy").equals("brightcove_admin") ) { - String requestedAccount = asset_res.getParent().getName(); + + String requestedAccount; + Node parentNode = asset_res.getParent().adaptTo(Node.class); + if (parentNode.hasProperty("brc_folder_id")) { + // this is not the actual account folder, so let's go up one more + requestedAccount = parentNode.getParent().getName(); + } else { + requestedAccount = parentNode.getName(); + } Resource metadataRes = asset_res.getChild("jcr:content/metadata"); ValueMap map = metadataRes.adaptTo(ValueMap.class); @@ -93,52 +101,6 @@ -
- - - - <% - String[] labels = map.get("brc_labels", String[].class); - if (labels != null) { - for (int i = 0; i < labels.length; i++) { - %> - - data-foundation-validation="" data-validation="" is="coral-textfield" - class="coral3-Textfield" aria-invalid="false"> - - - <% - } - } - %> - - - - -
- diff --git a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/brightcoveadmin.html b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/brightcoveadmin.html index 027453a..2246870 100644 --- a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/brightcoveadmin.html +++ b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/brightcoveadmin.html @@ -228,9 +228,11 @@

Video Preview + class="btn btn-primary btn-block">Video Preview

+
Variants: +
N/A

Duration:

Video ID: @@ -241,6 +243,12 @@

Tags:
+
+ + Labels: + Edit + +

Related Link:
diff --git a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/css/style.css b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/css/style.css index 7613185..18a1c15 100644 --- a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/css/style.css +++ b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/css/style.css @@ -1,35 +1,3 @@ -/* - Adobe AEM Brightcove Connector - - Copyright (C) 2018 Coresecure Inc. - - Authors: - Alessandro Bonfatti - Yan Kisen - Pablo Kropilnicki - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - - Additional permission under GNU GPL version 3 section 7 - If you modify this Program, or any covered work, by linking or combining - it with httpclient 4.1.3, httpcore 4.1.4, httpmine 4.1.3, jsoup 1.7.2, - squeakysand-commons and squeakysand-osgi (or a modified version of those - libraries), containing parts covered by the terms of APACHE LICENSE 2.0 - or MIT License, the licensors of this Program grant you additional - permission to convey the resulting work. - - */ body { background-color: #c3ddf6; font-family: adobe-clean,Helvetica,Arial,sans-serif; @@ -412,19 +380,46 @@ div.delConfPop { #searchDiv select, #searchDiv_pl select, #search_pl { height: 30px; + padding-left: 5px; + padding-right: 5px; } #divMeta.shortDescription pre { white-space: pre-wrap; + margin-top: 5px; +} + +#divMeta.labels a { + display: block; + margin-bottom: 2px; +} + +#tdMeta .variant { + display: block; + margin-bottom: 2px; +} + +.hdr-labels { + display: flex; + justify-content: space-between; } /* Create Playlist Styles */ -.pml-dialog .input-playlist-name { +.pml-dialog .input-playlist-name, .pml-dialog .input-label-name { display: block; width: 100%; margin-top: 10px; } +.pml-dialog .error { + border: 1px solid red; +} + +.pml-dialog details summary { + font-weight: bold; + margin-bottom: 2px; +} + div.hLine { border-color: white; border-style: solid; @@ -700,6 +695,10 @@ td.tdMetadata, th#trHeader { box-shadow: 0 0px 0px rgba(0, 0, 0, 0.075); } +.thumbnail a { + display: block; +} + input#search { height: 30px; } @@ -1452,12 +1451,12 @@ body { box-shadow: none; } -.pml-dialog .playlist-listing { +.pml-dialog .playlist-listing, .pml-dialog .label-listing { margin: 0; margin-top: 1rem; } -.pml-dialog .playlist-add-input input { +.pml-dialog .playlist-add-input input, .pml-dialog .label-add-input input { width: 100%; font-size: 1rem; font-family: adobe-clean,Helvetica,Arial,sans-serif; @@ -1465,14 +1464,15 @@ body { height: 30px; } -.pml-dialog .playlist-add-input .autocomplete { +.pml-dialog .playlist-add-input .autocomplete, .pml-dialog .label-add-input .autocomplete { position: relative; width: 100%; background: #fff; margin: 0; } -.pml-dialog .playlist-add-input .autocomplete .autocomplete-item { +.pml-dialog .playlist-add-input .autocomplete .autocomplete-item, +.pml-dialog .label-add-input .autocomplete .autocomplete-item { cursor: pointer !important; background-color: #e4eaf3; cursor: move; @@ -1484,13 +1484,10 @@ body { line-height: 1.7; } -.pml-dialog .playlist-listing li { +.pml-dialog .playlist-listing li, .pml-dialog .label-listing li { display: flex; justify-content: space-between; line-height: 1.7; -} - -.pml-dialog .playlist-listing li { cursor: move; margin: 4px 0; background: #f6f6f6; @@ -1498,7 +1495,7 @@ body { border-radius: 4px; } -.pml-dialog .playlist-listing li span .handle { +.pml-dialog .playlist-listing li span .handle, .pml-dialog .label-listing li span .handle { height: 15px; width: 15px; background-image: -webkit-gradient(linear, left top, left bottom, color-stop(50%, transparent), color-stop(50%, #f5f5f5)), -webkit-gradient(linear, left top, right top, color-stop(50%, #bebebe), color-stop(50%, transparent)); diff --git a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/js/brcAdmin.js b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/js/brcAdmin.js index 6e8892d..8bbdc18 100644 --- a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/js/brcAdmin.js +++ b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/js/brcAdmin.js @@ -182,9 +182,15 @@ function deleteVideoURL(videoId) { function showAllVideosCallBack(o) { if (null == o.error) { + var totals = o.totals; oCurrentVideoList = o.items; + if (!oCurrentVideoList) { + // the results are empty + oCurrentVideoList = new Array(); + totals = 0; + } buildMainVideoList("All Videos"); - doPageList(o.totals, "Videos"); + doPageList(totals, "Videos"); } else { var message = (null != o.error.message) ? o.error.message : o.error; console.log("Server Error: " + message); diff --git a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/js/brcUI.js b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/js/brcUI.js index 196e539..5ed48b0 100644 --- a/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/js/brcUI.js +++ b/current/ui.apps/src/main/content/jcr_root/apps/brightcove/components/tools/brightcoveadmin/clientlibs/js/brcUI.js @@ -32,7 +32,6 @@ //CONFIG -//FIX FOR PROBLEM 5.5 TODO:REMOVE $( document ).ready(function() { console.log($("#selAccount").val()); if(CQ.Ext!=null) @@ -120,15 +119,13 @@ $(function () { $('#searchDiv_pl').on('click', '.btn-create-playlist', function(event) { var $message = $('

Please enter a name for your playlist:

') - .append($('')); + .append($('')); showPopup('Create Playlist', $message.prop('outerHTML'), 'Create', 'Cancel', function(dialog) { - // call the API here. - // now reload the view - Load(getAllPlaylistsURL()); + // do something here }, function(dialog) { // do nothing here @@ -139,6 +136,10 @@ $(function () { $(event.target).parents('li').remove(); }) + $('.pml-dialog_content').on('click', '.label-listing li a', function(event) { + $(event.target).parents('li').remove(); + }) + $('#tbData').on('click', '.playlist-actions a', function(event) { event.preventDefault(); var playlist = { @@ -165,6 +166,7 @@ $(function () { // do something here? } }); + dialog.hide(); Load(getAllPlaylistsURL()); }, function(dialog) { @@ -197,6 +199,31 @@ $(function () { }; }); + $('.pml-dialog').on('keyup', '.label-add-input input', function(event) { + var query = $(event.target).val(); + var $parent = $(event.target).parents('.label-add-input'); + if (query) { + // perform an AJAX video search + var data = { + a: 'list_labels', + query: query, + start: 0, + limit: 3, + callback: 'suggestLabelsForVideo' + }; + $.ajax({ + type: 'GET', + url: '/bin/brightcove/api.js', + data: data, + async: true, + success: function (data) + { + // do something here? + } + }); + }; + }); + $('.folder-selector .menu-options').on('click', 'li', function(event) { var folderId = $(event.target).data('folder-id'); $.each(paging.selectedVideos, function (i, n) { @@ -255,6 +282,42 @@ $(function () { $('.butDiv').toggle(paging.selectedVideos.length > 0); }); + $('body').on('click', '.variant', function(event) { + event.preventDefault(); + var variantId = $(event.target).attr('data-variant-id'); + var videoId = $(event.target).attr('data-video-idx'); + var variant = oCurrentVideoList[videoId].variants[variantId]; + + var content = "
"; + content += "

Video Name:
" + variant.language + "

"; + + if (variant.description) + content += "

Description:
" + variant.description + "

"; + + if (variant.long_description) + content += "

Long Description:
" + variant.long_description + "

"; + + if (variant.custom_fields && JSON.stringify(variant.custom_fields) !== '{}') { + content += "

Custom Fields:

"; + for (const prop in variant.custom_fields) { + content += "
" + content += "" + prop + ""; + content += "

" + variant.custom_fields[prop] + "

"; + content += "
"; + } + } + + content += "
"; + + showPopup('Variant Details for Language: ' + variant.language, + content, + 'OK', + '', + function(dialog) { + dialog.hide(); + }); + }); + }); function showPopup(title, message, btnPrimaryText, btnSecondaryText, onSuccess, onCancel) { @@ -268,7 +331,6 @@ function showPopup(title, message, btnPrimaryText, btnSecondaryText, onSuccess, event.preventDefault(); if (onSuccess) onSuccess($popup); - $popup.hide(); }); if (btnSecondaryText) { $popup.find('.pml-dialog_footer .btn-secondary') @@ -288,6 +350,39 @@ function showPopup(title, message, btnPrimaryText, btnSecondaryText, onSuccess, $popup.show(); } +function suggestLabelsForVideo(data) { + $('.pml-dialog .autocomplete').empty(); + if (data.items.length > 0) { + $.each(data.items, function(i, n) { + if (n.includes($('.label-add-input input').val())) { + $('.pml-dialog .autocomplete') + .append( + $('
  • '+n+'
  • ') + .click(function(event) { + // assign a click handler to add that to the playlist + var $item = $(event.target); + + console.log($item); + + // make sure we have the autocomplete item and not the SVG icon + if ($item.localName == 'img') { + $item = $item.parent(); + } + var label = $item.attr('data-name'); + + // add the item to the list + $('.pml-dialog .label-listing') + .append($('
  • '+label+'
  • ')); + + // clear the search + $('.pml-dialog .label-add-input input').val(); + }) + ) + } + }) + } +} + function suggestVideosForPlaylist(data) { $('.pml-dialog .autocomplete').empty(); if (data.items.length > 0) { @@ -349,6 +444,9 @@ function getLabelListingUrl(id) { function loadFolders() { // first set up the select change event $('#fldr_list').on('change', function() { + // reset the label search + $('#label_list').val('all'); + $('.butDiv').hide(); var selected = $(this).val(); if (selected == 'all') { @@ -392,10 +490,52 @@ function loadFolderCallback(data) { function loadLabels() { // first set up the select change event $('#label_list').on('change', function() { + // reset the folder search + $('#fldr_list').val('all'); + $('.butDiv').hide(); var selected = $(this).val(); if (selected == 'all') { Load(getAllVideosURL()); + } else if (selected == 'create') { + var $message = + $('

    Label Name:

    ') + .append($('')); + showPopup('Create New Label', + $message.prop('outerHTML'), + 'Create', + 'Cancel', + function(dialog) { + + // do some basic validationĂ¥ + var labelName = $('.input-label-name').val(); + if (labelName == '' || !labelName.startsWith('/')) { + $('.input-label-name').addClass('error'); + } else { + $('.input-label-name').removeClass('error'); + // call the API here. + var data = { + a: 'create_label', + label: labelName + }; + $.ajax({ + type: 'GET', + url: '/bin/brightcove/api.js', + data: data, + async: true, + success: function (data) + { + // do something here? + } + }); + dialog.hide(); + location.reload(); + } + }, + function(dialog) { + // do nothing here + triggerLabelClick('all'); + }) } else { console.log('search videos by label=' + selected); Load(getLabelListingUrl(selected)); @@ -419,13 +559,62 @@ function loadLabels() { }); } +function editLabels(event) { + var data = { + videoId: document.getElementById('divMeta.previewDiv').value, + items: $(document.getElementById('divMeta.labels')).find('a').map(function() { + return $(this).text() + }) + .get() + }; + console.log(data.items); + var $search = $('
      ').prop('outerHTML'); + var $message = $('
        '); + data.items.forEach(function(item, index) { + $message + .append($('
      • '+item+'
      • ')); + }); + showPopup('Edit Labels', $search + $message.prop('outerHTML'), 'Update', 'Cancel', function(event) { + var playlistData = { + a: 'update_labels', + labels: $('#edit-labels-sortable') + .find('li') + .map(function(item) { return $(this).text() }).get(), + videoId: data.videoId + }; + + $.ajax({ + type: 'GET', + url: '/bin/brightcove/api.js', + data: $.param(playlistData, true), + async: true, + success: function (data) + { + location.reload(); + } + }); + + event.hide(); + }, null); + var el = document.getElementById("edit-labels-sortable"); + $sortable = Sortable.create(el); +} + +function callback(data) { + // generic callback +} + function loadLabelCallback(data) { var $label_select = $('#label_list'); $.each(data.items, function (i, n) { - console.log(n); $label_select - .append($('