Shadow Assets Vimeo Provider

Advanced-UI

The plugin creates the node structure in Celum starting from a configurable Vimeo root folder. Afterwards the Vimeo videos are created as shadow assets in Celum.

Properties

To be configured in {home}/appserver/conf/custom.properties.

vimeoShadowAssetsProvider.license

type: String, required: yes, default: -

The license key for the plugin (product: vimeoShadowAssetsProvider), provided by brix.

Vimeo oAuth

For the authentication, the OAuthCodeStorage plugin is necessary. For details visit Vimeo.

vimeoShadowAssetsProvider.oAuth.clientId

type: String, required: yes, default: -

Vimeo client id for authentication, provided by Vimeo.

vimeoShadowAssetsProvider.oAuth.clientSecret

type: String, required: yes, default: -

Vimeo client secret for authentication, provided by Vimeo.

vimeoShadowAssetsProvider.oAuth.requiredScopes

type: List of String (comma-separated), required: yes, default: public,private,video_files

Vimeo access scopes.

vimeoShadowAssetsProvider.oAuth.oAuthProfile

type: String, required: yes, default: -

OAuth profile name of the Access Token storage, has to be the same name as used in the oAuth Code Storage plugin for storing the Vimeo access token.


Provider Configuration

Shadow Assets Provider Config

For setting up the shadow assets base configuration visit the internal Documentation.

shadowAssetsMappings

All primitive Vimeo-API fields can be mapped automatically. To do so, create a shadow asset mapping with the field named the same as the Vimeo field. For example, if you want to map the Vimeo-API field video.created_time define a ShadowAssetsMapping as followed:

  <bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
      <property name="field"
                value="created_time"/> <!-- make sure the name of the field is the same as the vimeo video field name   -->
       <property name="mapping">
                <bean class="ch.brix.shadowAssets.lib.mappingTypes.infofield.TextInfofieldMapping">
                    <property name="infofieldId" value="206"/>
                    <property name="doUpdateCheck" value="true"/>
                    <property name="clearOnEmptyValue" value="true"/>
                </bean>
      </property>
  </bean>

Additionally, the Vimeo-API fields video.tags and video.categories are also automatically mapped. To use this feature, create another ShadowAssetsMapping as followed:

<!--    tags   -->
<bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
    <property name="field"
              value="tags"/>
    <property name="mapping">
        <bean class="ch.brix.shadowAssets.lib.mappingTypes.infofield.NodeReferencingInfofieldByMultiNameMapping">
            <property name="infofieldId" value="208"/>
            <property name="clearOnEmptyValue" value="true"/>
            <property name="exclusive" value="true"/>
            <property name="doUpdateCheck" value="true"/>
            <property name="nodeFinder">
                <bean class="ch.brix.shadowAssets.lib.nodeFinder.DefaultNodeFinder">
                    <property name="rootNodeId" value="10602"/>
                    <property name="createIfNotFound" value="true"/>
                </bean>
            </property>
        </bean>
    </property>
</bean>
<!--    category   -->
<bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
    <property name="field"
              value="categories"/>
    <property name="mapping">
        <bean class="ch.brix.shadowAssets.lib.mappingTypes.infofield.NodeReferencingInfofieldByMultiNameMapping">
            <property name="infofieldId" value="210"/>
            <property name="clearOnEmptyValue" value="true"/>
            <property name="exclusive" value="true"/>
            <property name="doUpdateCheck" value="true"/>
            <property name="nodeFinder">
                <bean class="ch.brix.shadowAssets.lib.nodeFinder.DefaultNodeFinder">
                    <property name="rootNodeId" value="10692"/>
                    <property name="createIfNotFound" value="true"/>
                </bean>
            </property>
        </bean>
    </property>
</bean>

complexMappings

If the automatic mappings provided are not enough, implement the ShadowAssetsComplexMapping interface, see Example. All requested Vimeo-API fields are stored in the details (apart from name and uri/id). See Vimeo-API-Reference for more information (Link).

Vimeo Shadow Assets Provider Config

In addition to the base configuration the vimeo provider expects the following to be defined in the provider bean located in {home}/appserver/spring/shadowAssetsMapping.xml.

Shadow Assets Config

For details visit the documentation Shadow Assets.

assetTypeId

type: AssetTypeId, required: yes (for create), default: -

See assetTypeId for details. All vimeo videos have the same asset type for each provider.

versioning

type: boolean, required: no, default: true

If set to true, versioning is enabled.

thumbnails

type: boolean, required: no, default: true

If set to true, thumbnails will be downloaded.

Automatic configuration
  • targetNodeId: The target node is derived from the Vimeo-API field video.parent_folder.uri and is created automatically.
  • externalID: The ID provided in the Vimoe-API field video.uri is used.
  • originalURL: If available, a public url stored in the Vimeo-API field video.link is created with the defined provider description.
  • additionalPublicUrls: If available, a public url stored in the Vimeo-API field video.player_embed_url is created with Player Link as description.
  • name and originalFilename: The value stored in the Vimeo-API field video.nameis used.
  • thumbURL: If thumbnails is true, thumbnails from the Vimeo-API field video.pictures.base_link will be downloaded.
    • For further details visit the internal documentation Shadow Assets
  • filetypeMapping: If guessFileCategory is true, file category is set to VIDEO.
  • version: If versioning is true, versions will be created and derived from the Vimeo-API field video.metadata.connections.versions.current_uri.
    • For further details visit the internal documentation Shadow Assets

Vimeo Config

vimeoUser

type: long, required: yes, default: -

The Vimeo User that is used to search for videos and folders.

vimeoRootFolders

type: List of long (comma-separated), required: yes, default: -

All items (videos and folders) including rootfolders are created in Celum.

vimeoVideoFields

type: List of String (comma-separated), required: no, default: -

If defined, only the defined fields plus mandatory fields (video.uri,video.name,video.parent_folder.uri) are requested from Vimeo. Otherwise, all fields are requested.

Example: video.player_embed_url,video.pictures.base_link,video.created_time

Node Config

As there are no metadata on Vimeo folders, only the ID and the folder name will be mapped to nodes.

folderNodeTypeId

type: NodeTypeId, required: yes (if folderRootNodeId not set), default: -

If set, nodes for Vimeo folder will be created in the definded nodetype, as a root node if folderRootNodeId is not defined.

folderRootNodeId

type: NodeId, required: yes (if folderNodeTypeId not set), default: -

If set, nodes for Vimeo folder will be created in the root node.

folderExternalIdInfofield

type: InformationFieldId, required: yes, default: -

Node infofield to identify Vimeo folders. Has to be unique for each provider. Only of type Text oder Number.

vimeoFolderNodeFinder

type: InfofieldNodeFinder, required: yes, default: -

Used to find the target node for a shadow asset and to create folder structure based on the external ID. The InfofieldNodeFinder searchs by value in the specified infofield, only Text and Number Infofields are supported.

<property name="vimeoFolderNodeFinder">
  <bean class="ch.brix.shadowAssets.lib.nodeFinder.InfofieldNodeFinder">
    <property name="informationFieldId" value="${vimeoOneShadowAssetsProvider.node.externalIdInfofield}"/>
    <property name="nodeTypeId" value="${vimeoOneShadowAssetsProvider.node.nodeTypeId}"/>
  </bean>
</property>       

Task Config

storageKey

type: String, required: yes, default: -

Used to store the tasktime in the global storage, needs to be unique for each provider.


Tasks

The plugin provides three different tasks that are defined in located in {home}/appserver/spring/shadowAssetsMapping.xml

Gets all videos and folders.

<bean id="vimeoOneFullSyncTask" class="ch.brix.shadowAssetsVimeoProvider.tasks.VimeoShadowAssetsFullSyncTask">
    <constructor-arg ref="vimeoOneShadowAssetsProvider"/>
</bean>

Gets all videos and folders with modiefied date >= last task run time

<bean id="vimeoOneDeltaSyncTask" class="ch.brix.shadowAssetsVimeoProvider.tasks.VimeoShadowAssetsDeltaSyncTask">
    <constructor-arg ref="vimeoOneShadowAssetsProvider"/>
</bean>

All videos and folders that are in Celum but no longer in Vimeo are deleted.

<bean id="vimeoOneDeleteSyncTask" class="ch.brix.shadowAssetsVimeoProvider.tasks.VimeoShadowAssetsDeleteSyncTask">
    <constructor-arg ref="vimeoOneShadowAssetsProvider"/>
</bean>

Example

To be configured in {home}/appserver/conf/custom.properties.

#### Shadow Assets #####
shadowAssets.license=**************

#### Vimeo Shadow Assets #####

## oAuth
vimeoShadowAssetsProvider.oAuth.clientId=**************
vimeoShadowAssetsProvider.oAuth.clientSecret=**************
vimeoShadowAssetsProvider.oAuth.oAuthProfile=shadowAssets

## vimeoOneShadowAssetsProvider

# shadow assets config
vimeoOneShadowAssetsProvider.providerName=Vimeo One Provider
vimeoOneShadowAssetsProvider.providerDescription=Vimeo Shadow Asset Provider One
vimeoOneShadowAssetsProvider.infoFieldExternalId=204
vimeoOneShadowAssetsProvider.guessFileCategory=true
vimeoOneShadowAssetsProvider.assetTypeId=3000
vimeoOneShadowAssetsProvider.versioning=true
vimeoOneShadowAssetsProvider.thumbnails=true

# shadow assets task
vimeoOneShadowAssetsProvider.task.storageKey=vimeoonetasks

# vimeo Config
vimeoOneShadowAssetsProvider.vimeo.user=123456
vimeoOneShadowAssetsProvider.vimeo.rootFolders=123456
vimeoOneShadowAssetsProvider.vimeo.videoFields=video.created_time,video.modified_time,video.tags.name,video.categories.name,video.content_rating,video.metadata.connections.versions.current_uri,video.pictures.base_link,video.link,video.player_embed_url

# node config
vimeoOneShadowAssetsProvider.node.nodeTypeId=105
vimeoOneShadowAssetsProvider.node.externalIdInfofield=209

To be configured in {home}/appserver/spring/shadowAssetsMapping.xml.

   <bean id="vimeoOneShadowAssetsProvider" class="ch.brix.shadowAssetsVimeoProvider.VimeoShadowAssetsProvider">
  <property name="providerName" value="${vimeoOneShadowAssetsProvider.providerName}"/>
  <property name="providerDescription" value="${vimeoOneShadowAssetsProvider.providerDescription}"/>
  <property name="infoFieldExternalId" value="${vimeoOneShadowAssetsProvider.infoFieldExternalId}"/>
  <property name="guessFileCategory" value="${vimeoOneShadowAssetsProvider.guessFileCategory}"/>
  <property name="shadowAssetsMappings" ref="vimeoOneShadowAssetsMappings"/>
  <property name="infofieldsToLoad">
    <list>
      <value>${vimeoOneShadowAssetsProvider.infoFieldExternalId}</value> <!-- vimeo_video_id -->
      <value>205</value> <!-- vimeo_video_name -->
      <value>206</value> <!-- vimeo_video_created_time -->
      <value>207</value> <!-- vimeo_video_modified_time -->
      <value>208</value> <!-- vimeoTags -->
      <value>210</value> <!-- vimeoCategories -->
    </list>
  </property>

  <property name="assetTypeId" value="${vimeoOneShadowAssetsProvider.assetTypeId}"/>
  <property name="versioning" value="${vimeoOneShadowAssetsProvider.versioning}"/>
  <property name="thumbnails" value="${vimeoOneShadowAssetsProvider.thumbnails}"/>

  <property name="storageKey" value="${vimeoOneShadowAssetsProvider.task.storageKey}"/>

  <property name="vimeoUser" value="${vimeoOneShadowAssetsProvider.vimeo.user}"/>
  <property name="vimeoRootFolders" value="${vimeoOneShadowAssetsProvider.vimeo.rootFolders}"/>
  <property name="vimeoVideoFields" value="${vimeoOneShadowAssetsProvider.vimeo.videoFields}"/>

  <property name="folderNodeTypeId" value="${vimeoOneShadowAssetsProvider.node.nodeTypeId}"/>
  <property name="folderExternalIdInfofield" value="${vimeoOneShadowAssetsProvider.node.externalIdInfofield}"/>
  <property name="vimeoFolderNodeFinder">
    <bean class="ch.brix.shadowAssets.lib.nodeFinder.InfofieldNodeFinder">
      <property name="informationFieldId" value="${vimeoOneShadowAssetsProvider.node.externalIdInfofield}"/>
      <property name="nodeTypeId" value="${vimeoOneShadowAssetsProvider.node.nodeTypeId}"/>
    </bean>
  </property>

  <property name="complexMappings" ref="vimeoOneComplexMapping"/>
</bean>

<bean id="vimeoOneComplexMapping" class=" ch.brix.shadowAssetsComplexMappingVimeoOne.ShadowAssetsComplexMappingVimeoOne"/>

<bean id="vimeoOneFullSyncTask" class="ch.brix.shadowAssetsVimeoProvider.tasks.VimeoShadowAssetsFullSyncTask">
<constructor-arg ref="vimeoOneShadowAssetsProvider"/>
</bean>

<bean id="vimeoOneDeltaSyncTask" class="ch.brix.shadowAssetsVimeoProvider.tasks.VimeoShadowAssetsDeltaSyncTask">
<constructor-arg ref="vimeoOneShadowAssetsProvider"/>
</bean>

<bean id="vimeoOneDeleteSyncTask" class="ch.brix.shadowAssetsVimeoProvider.tasks.VimeoShadowAssetsDeleteSyncTask">
<constructor-arg ref="vimeoOneShadowAssetsProvider"/>
</bean>

<util:list id="vimeoOneShadowAssetsMappings" value-type="ch.brix.shadowAssets.ShadowAssetsMapping">

<!--    created time   -->
<bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
  <property name="field"
            value="created_time"/>
  <property name="mapping">
    <bean class="ch.brix.shadowAssets.lib.mappingTypes.infofield.TextInfofieldMapping">
      <property name="infofieldId" value="206"/>
      <property name="doUpdateCheck" value="true"/>
      <property name="clearOnEmptyValue" value="true"/>
    </bean>
  </property>
</bean>

<!--    modified time   -->
<bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
  <property name="field"
            value="modified_time"/>
  <property name="mapping">
    <bean class="ch.brix.shadowAssets.lib.mappingTypes.infofield.TextInfofieldMapping">
      <property name="infofieldId" value="207"/>
      <property name="doUpdateCheck" value="true"/>
      <property name="clearOnEmptyValue" value="true"/>
    </bean>
  </property>
</bean>

<!--    tags   -->
<bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
  <property name="field"
            value="tags"/>
  <property name="mapping">
    <bean class="ch.brix.shadowAssets.lib.mappingTypes.infofield.NodeReferencingInfofieldByMultiNameMapping">
      <property name="infofieldId" value="208"/>
      <property name="clearOnEmptyValue" value="true"/>
      <property name="exclusive" value="true"/>
      <property name="doUpdateCheck" value="true"/>
      <property name="nodeFinder">
        <bean class="ch.brix.shadowAssets.lib.nodeFinder.DefaultNodeFinder">
          <property name="rootNodeId" value="10602"/>
          <property name="createIfNotFound" value="true"/>
        </bean>
      </property>
    </bean>
  </property>
</bean>

<!--    category   -->
<bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
  <property name="field"
            value="categories"/>
  <property name="mapping">
    <bean class="ch.brix.shadowAssets.lib.mappingTypes.infofield.NodeReferencingInfofieldByMultiNameMapping">
      <property name="infofieldId" value="210"/>
      <property name="clearOnEmptyValue" value="true"/>
      <property name="exclusive" value="true"/>
      <property name="doUpdateCheck" value="true"/>
      <property name="nodeFinder">
        <bean class="ch.brix.shadowAssets.lib.nodeFinder.DefaultNodeFinder">
          <property name="rootNodeId" value="10692"/>
          <property name="createIfNotFound" value="true"/>
        </bean>
      </property>
    </bean>
  </property>
</bean>
</util:list>

Complex Mapping Implementation.

public class ShadowAssetsComplexMappingVimeoOne implements ShadowAssetsComplexMapping {

  @Override
  public void doComplexMapping(ShadowAsset shadowAsset, Map<String, Object> details) {
    try {
      if (shadowAsset.getAdditionalPublicUrls() == null) shadowAsset.setAdditionalPublicUrls(new HashMap<>());
      shadowAsset.getAdditionalPublicUrls().put("another public url", "www.test.ch");
      ArrayList<String> contentRatingList = (ArrayList) details.get("content_rating");
      String contentRating = null;
      if (contentRatingList != null && !contentRatingList.isEmpty()) {
        contentRating = contentRatingList.stream().collect(Collectors.joining(";"));
      }
      shadowAsset.getMetadata().put("content_rating", Collections.singletonList(contentRating));
    } catch (Exception e) {
      log.error("Failed to do complex mapping for shadow asset " + shadowAsset.getExternalID(), e);
    }

  }
}

Compatibility Matrix

Shadow Assets Vimeo Provider CELUM (min. version) Shadow Assets
1.0.0 6.4 (tested with 6.12) 1.2.8

Release Notes

1.0.0

Release: 2023-03-27

Initial Version