Sunday 19 June 2016

Retrieving videos from o365 video portal in multiple ways

In this post, we will see how we can retrieve videos and related information from o365 video portal with multiple ways. First we will see how we can retrieve all the videos from the portal using content type and also we will see how we can retrieve videos from the portal with multiple filters.


Retrieve All Videos Using Site Content Type ID:

The videos are stored on the portal using cloud video content type. At the video library (list level), the cloud video content type will differ for multiple channels. Also this content type will differ on various sites. Video cloud content type is present at site level. The content type id of video cloud will be common for any o365 portal. The content type id is 0x010100F3754F12A9B6490D9622A01FE9D8F012. It is 40 digits.

At the library level, the video cloud content type id consists of 74 digits. But first 40 digits will be common, since the list level video cloud content type is inherited from site level video cloud content type.

Using REST Search API, the all the videos present across various channels can be retrieved from the portal in a single call with site level cloud video content type. In the query text, we will pass the content type id by appending '*'. So that all the videos which has the content type starting with the same digits will be retrieved.

The Search API will be,
/_api/search/query?QueryText=%27contenttypeid:0x010100F3754F12A9B6490D9622A01FE9D8F012*%27

The results are based on search indexing. The crawl should run periodically to get the video results. And also the properties retrieved here will be more focused on analytical information with some basic video properties. The information like processing status, video running time, channel information will not be retrieved here.  

The following code snippet shows the JQuery Ajax call to get the videos from Office 365 video portal, using REST search API:

  1. $.ajax({  
  2.     url: "/_api/search/query?QueryText=%27contenttypeid:0x010100F3754F12A9B6490D9622A01FE9D8F012*%27",  
  3.     type: "GET",  
  4.     async: false,  
  5.     headers: { "accept""application/json;odata=verbose" },  
  6.     success: function(data){  
  7.         var videosInfo = data.d.query.PrimaryQueryResult.RelevantResults;  
  8.           
  9.         console.log("Available Videos Count on Channel : " + videosInfo.RowCount);  
  10.     var videoResults = videosInfo.Table.Rows.results;  
  11.     for(var i = 0; i< videoResults.length; i++){  
  12.         console.log("Title : "+videoResults[i].Cells.results[3].Value);  
  13.         console.log("Created By : "+videoResults[i].Cells.results[4].Value);  
  14.         console.log("Video URL : "+videoResults[i].Cells.results[6].Value);  
  15.     }  
  16.     //Similarly other results can be retrieved and displayed  
  17.     },  
  18.     error: function(data){  
  19.     }  
  20. });  

The necessary parameters can be only be retrieved using selectProperties option in the API. The example looks like, 
/_api/search/query?QueryText=%27contenttypeid:0x010100F3754F12A9B6490D9622A01FE9D8F012*%27&selectproperties=%27Title%27


Retrieve Videos using Video & List APIs:

The REST Video API used to retrieve the videos from channel will be,
https://videoportalurl/_api/VideoService/Channels('channelid')/GetAllVideos

Here we will see various ways to filter out the videos from the portal. 

The video results here are instant results. More information like processing status, video download URL, owner details, running information, tags, channel and other basic information can be retrieved instantly. Here we can get the required parameters for videos using select parameters. The properties which are retrieved from the operation can be used in the select parameters to retrieve only specific information. For example, in the following example, we have retrieved only file name and video url using the REST API.

User can apply following use cases for retrieving videos. 
  • User can get only playable(processed) videos by applying processing status filter. (VideoProcessingStatus:2)
  • User can get only incomplete videos by applying the status filter (Not processed). (VideoProcessingStatus:1)
  • Filter only videos with the known property values. (AnyProperty:Value)
  • Most played videos (Sort Asc/desc using VideoDurationInSeconds)
 There are many other scenarios where filter and other parameters can be used to retrieve videos with REST Video API. These filter functionalities are available with REST List API as well. 

The API will look like,
https://videoportalurl/_api/VideoService/Channels('channelid')/GetAllVideos?$select=FileName, ServerRelativeUrl,Author&$expand=Author/Name&$filter=VideoProcessingStatus eq 2

OR

https://channelsiteURL/_api/web/lists/GetByTitle('Videos')/Items?$filter= VideoProcessingStatus eq 2

Both the above API will get same set of JSON response, which can be processed and displayed. But the response is different from search API response.

The following code snippet shows the Jquery Ajax call to get the videos present on the specified channel with filters and select parameters, using REST List API:
  1. $.ajax  
  2. ({    
  3.     url: "https://chennal_url/_api/web/lists/GetByTitle('Videos')/Items?$select=Title&$filter=VideoProcessingStatus eq 2",    
  4.     type: "GET",    
  5.     async: false,    
  6.     headers: { "accept""application/json;odata=verbose" },    
  7.     success: function(data){    
  8.         if(data.d != null && data.d.results.length > 0){    
  9.             var videoResults = data.d.results;    
  10.                 
  11.                 
  12.         for(var i = 0; i< videoResults.length; i++){    
  13.             console.log("Title : "+videoResults[i].Title);      
  14.         }    
  15.     }    
  16.     //Similarly other results can be retrieved and displayed    
  17.     },    
  18.     error: function(data){    
  19.     }    
  20. });   
The following code snippet shows the Jquery Ajax call to get the videos present on the specified channel with filters and select parameters, using REST Video API:
  1. $.ajax({  
  2.     url: "https://videoportal_url/_api/VideoService/Channels('channelid')/GetAllVideos?$select=Title&$filter=VideoProcessingStatus eq 2",  
  3.     type: "GET",  
  4.     async: false,  
  5.     headers: { "accept""application/json;odata=verbose" },  
  6.     success: function(data){  
  7.         if(data.d != null && data.d.results.length > 0){  
  8.             var videoResults = data.d.results;  
  9.             for(var i = 0; i< videoResults.length; i++){  
  10.                 console.log("Title : "+videoResults[i].Title);  
  11.             }  
  12.         }  
  13.         //Similarly other results can be retrieved and displayed  
  14.     },  
  15.     error: function(data){  
  16.     }  
  17. });  

Note: Thus you have learned how to retrieve video details using REST search, REST video and REST list APIs with filter and select parameters. Also we understood the basic difference in getting the response using various REST API methods.

Saturday 18 June 2016

Add Custom Tabs and Groups to the Ribbon on SharePoint using CSOM PowerShell


In this post, you will learn how to add custom ribbon tabs, ribbon groups and ribbon items (user actions) for for list using CSOM Powershell on SharePoint 2013 / SharePoint 2016 / SharePoint online sites.


Steps Involved:

The following prerequisites are required to be executed, before going for any operations, using CSOM PowerShell on SharePoint sites.
  1. Add the references, using the Add-Type command with the necessary reference paths. The necessary references are Client.dll, Client.Runtime.dll and publishing.dll.
    1. Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"  
    2. Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"  
    3. Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Publishing.dll"  
  2. Initialize the client context object with the site URL.
    1. $siteURL = ""  
    2. $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteURL)  
  3. If you are trying to access SharePoint Online site, then you need to setup the site credentials with the credentials parameter and load it to the client context. 
    1. #Not required for on premise site - Start  
    2. $userId = ""  
    3. $pwd = Read-Host -Prompt "Enter password" -AsSecureString  
    4. $creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($userId, $pwd)  
    5. $ctx.credentials = $creds  
    6. #Not required for on premise site - End  
  4. If you are trying to access the SharePoint on premise site, then the credentials parameter is not required to be set to the context but you need to run the code on the respective SharePoint Server or you need to pass the network credentials and set the context.
    1. #Credentials for on premise site - Start  
    2. $pwd = Read-Host -Prompt "Enter password" -AsSecureString  
    3. $creds = New-Object System.Net.NetworkCredential("domain\userid", $pwd)  
    4. $ctx.Credentials = $creds  
    5. #Credentials for on premise site - End  
We will see, how we can add the custom ribbon tabs and other components to the SharePoint list ribbon.
  • Get the existing user action collection. Access the Web and get the existing user actions, using UserCustomActions property. Load and execute the property.
  • Add new custom action to the user actions collection. The necessary parameters for new action are registration ID, title, registration type and location. Here we need to set the ribbon tab values.
    • Registration ID - Corresponding List template ID to add the user action. For example, here 100 denotes the custom list templates.
    • Registration Type - Denotes association type.
    • Location - Custom action location.
  • Build the XML for the new extension. The following are the steps considered. 
    • New custom tab has been added to the ribbon. 
    • Then new group has been associated with the tab created. 
    • Then custom control (button) is added to the group created.
  • Update and execute to see the changes.
The XML extension contains the following elements.
  • New definition for tab with specified ribbon location. The tab will contain scaling and groups components.
    • The scaling will denote the behaviour of tab (sizing). Size is associated to the layout title under the group template.
    • The groups can have one or more group elements. Each group will have the properties like title, description, template (associated to group template) and id. And group also contains controls to be associated. The controls can button, label, etc. 
      • For each control, set the necessary parameters. The command parameter is associated to UIHandler. The TemplateAlias should match alias name defined for the control under group template.
  • Another definition for group template needs to be created. Here, the new template details for the group, layout mapping and display mode (size) for controls are defined.
  • The UIHandler section contains necessary javascript function for the controls defined. 
The following piece of code shows the operation with necessary XML.
  1. $web = $ctx.Site.RootWeb  
  2. $userActions = $web.UserCustomActions  
  3. $ctx.Load($userActions)   
  4. $ctx.ExecuteQuery()   
  5.   
  6. $newRibbonItem = $userActions.Add()  
  7. $newRibbonItem.RegistrationId = "100"  
  8. $newRibbonItem.Title = "Custom Ribbon Tab"  
  9. $newRibbonItem.RegistrationType = [Microsoft.SharePoint.Client.UserCustomActionRegistrationType]::List  
  10. #$newRibbonItem.Id = "Ribbon.CustomTab"  
  11. $newRibbonItem.Location = "CommandUI.Ribbon"  
  12.   
  13. $ribbonUI = '<CommandUIExtension>  
  14.                     <CommandUIDefinitions>  
  15.                         <CommandUIDefinition Location="Ribbon.Tabs._children">  
  16.                             <Tab Id="Ribbon.CustomTab" Title="Custom Tab" Description="Custom Tab with groups and user action" Sequence="100">  
  17.                                 <Scaling Id="Ribbon.CustomTab.Scaling">  
  18.                                     <MaxSize Id="Ribbon.CustomTab.CustomGroup1.MaxSize"  
  19.                                         GroupId="Ribbon.CustomTab.CustomGroup1"  
  20.                                         Size="LargeLayout" />  
  21.                                 </Scaling>  
  22.                                 <Groups Id="Ribbon.CustomTab.CustomGroups">  
  23.                                     <Group Id="Ribbon.CustomTab.CustomGroup1"  
  24.                                         Description="Collection of user actions"  
  25.                                         Title="CustomGroup1"  
  26.                                         Sequence="20"  
  27.                                         Template="Ribbon.Templates.LargeLayout">  
  28.                                         <Controls Id="Ribbon.CustomTab.CustomGroup1.Controls">  
  29.                                             <Button Id="Ribbon.CustomTab.CustomGroup1.ShowAlert" Alt="Show Alert" Sequence="101"  
  30.                                                  Command="ShowRibbonAlert"  
  31.                                                  LabelText="Custom Alert"  
  32.                                                  Image32by32="_layouts/15/images/alertme.png"  
  33.                                                  Image16by16="_layouts/15/images/alertme.png"  
  34.                                                  TemplateAlias="ButtonTemplate" />  
  35.                                         </Controls>  
  36.                                     </Group>  
  37.                                 </Groups>  
  38.                             </Tab>  
  39.   
  40.                        </CommandUIDefinition>  
  41.                         <CommandUIDefinition Location="Ribbon.Templates._children">   
  42.                             <GroupTemplate Id="Ribbon.Templates.LargeLayout">   
  43.                                 <Layout Title="LargeLayout" LayoutTitle="LargeLayout">   
  44.                                     <Section Alignment="Top" Type="OneRow">   
  45.                                         <Row>   
  46.                                             <ControlRef DisplayMode="Large" TemplateAlias="ButtonTemplate" />   
  47.                                         </Row>   
  48.                                     </Section>   
  49.                                 </Layout>   
  50.                             </GroupTemplate>   
  51.                         </CommandUIDefinition>  
  52.                     </CommandUIDefinitions>  
  53.                     <CommandUIHandlers>  
  54.                         <CommandUIHandler Command="ShowRibbonAlert"  
  55.                              CommandAction="javascript:alert(''hi'');"/>  
  56.                     </CommandUIHandlers>  
  57.                 </CommandUIExtension >'  
  58.   
  59. $newRibbonItem.CommandUIExtension = $ribbonUI  
  60. $newRibbonItem.Update()  
  61. $ctx.Load($newRibbonItem)  
  62. $ctx.ExecuteQuery()  

The following image shows the tab along with group and control.