Module cvpysdk.download_center
File for doing operations on Download Center.
DownloadCenter is the class defined in this module for doing operations on the Download Center.
Following Operations can be performed on the Download Center:
1. Add a new category to Download Center
2. Add a new sub category to the specified category to Download Center
3. Upload a package to Download Center
4. Download a package from Download Center
5. Delete a sub category from the specified category on Download Center
6. Delete a category from Download Center
7. Delete a package from Download Center
8. Update the category information
9. Update the sub category information for the specified category
Downloadcenter
init(commcell_object) – initializes a connection to the download center
repr() – returns the string representation of an instance of this class
_get_properties() – get the properties of the download center
_get_packages() – get the packages available at download center
_process_category_request() – executes the request on the server, and parses the response
_process_sub_category_request() – executes the request on the server, and parses the response
sub_categories() – returns the sub categories available for the given category
get_package_details() – returns the details of the package specified
add_category() – adds a new category to the download center
update_category() – updates the category details at the download center
delete_category() – deletes the given category from the download center
add_sub_category() – adds a new sub category to the specified category
update_sub_category() – updates the sub category details for the given catetory at the download center
delete_sub_category() – deletes the specified sub category for the given category from the download center
upload_package() – uploads the given package to download center
download_package() – downloads the given package from download center
delete_package() – deletes the given package from download center
refresh() – refresh the properties of the download center class instance
Attributes
Following attributes are available for an instance of the Download Center class:
**product_versions** -- returns list of product versions supported on Download Center
**servers_for_browse** -- returns the list of servers available for browse on DC
**error_detail** -- errors returned while getting the Download Center attributes
**users_and_groups** -- returns the list of users and user groups available at DC
**categories** -- returns the list of categories available at Download Center
**download_types** -- returns the list of supported download types for packages
**vendors** -- returns the list of vendors available at Download Center
**platforms** -- returns the list of supported platforms for DC packages
**packages** -- returns the list of packages available at Download Center
TODO: implement update method for updating details of a package
TODO: add a PS script to be called via commcell client, to check if the location is valid,
and get the size of the file
Expand source code Browse git
# -*- coding: utf-8 -*-
# --------------------------------------------------------------------------
# Copyright Commvault Systems, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# --------------------------------------------------------------------------
"""File for doing operations on Download Center.
DownloadCenter is the class defined in this module for doing operations on the Download Center.
Following Operations can be performed on the Download Center:
1. Add a new category to Download Center
2. Add a new sub category to the specified category to Download Center
3. Upload a package to Download Center
4. Download a package from Download Center
5. Delete a sub category from the specified category on Download Center
6. Delete a category from Download Center
7. Delete a package from Download Center
8. Update the category information
9. Update the sub category information for the specified category
DownloadCenter:
__init__(commcell_object) -- initializes a connection to the download center
__repr__() -- returns the string representation of an instance of this class
_get_properties() -- get the properties of the download center
_get_packages() -- get the packages available at download center
_process_category_request() -- executes the request on the server, and parses the response
_process_sub_category_request() -- executes the request on the server, and parses the response
sub_categories() -- returns the sub categories available for the given category
get_package_details() -- returns the details of the package specified
add_category() -- adds a new category to the download center
update_category() -- updates the category details at the download center
delete_category() -- deletes the given category from the download center
add_sub_category() -- adds a new sub category to the specified category
update_sub_category() -- updates the sub category details for the given catetory
at the download center
delete_sub_category() -- deletes the specified sub category for the given category
from the download center
upload_package() -- uploads the given package to download center
download_package() -- downloads the given package from download center
delete_package() -- deletes the given package from download center
refresh() -- refresh the properties of the download center class instance
Attributes:
Following attributes are available for an instance of the Download Center class:
**product_versions** -- returns list of product versions supported on Download Center
**servers_for_browse** -- returns the list of servers available for browse on DC
**error_detail** -- errors returned while getting the Download Center attributes
**users_and_groups** -- returns the list of users and user groups available at DC
**categories** -- returns the list of categories available at Download Center
**download_types** -- returns the list of supported download types for packages
**vendors** -- returns the list of vendors available at Download Center
**platforms** -- returns the list of supported platforms for DC packages
**packages** -- returns the list of packages available at Download Center
# TODO: implement update method for updating details of a package
# TODO: add a PS script to be called via commcell client, to check if the location is valid,
and get the size of the file
"""
from xml.parsers.expat import ExpatError
import os
import time
import xmltodict
from .exception import SDKException
class DownloadCenter(object):
"""Class for doing operations on Download Center like upload or download product."""
def __init__(self, commcell_object):
"""Initializes an instance of the DownloadCenter class.
Args:
commcell_object (object) -- instance of the Commcell class
Returns:
object - instance of the DownloadCenter class
"""
self._commcell_object = commcell_object
self._cvpysdk_object = commcell_object._cvpysdk_object
self._services = commcell_object._services
self._update_response_ = commcell_object._update_response_
self._response = None
self.refresh()
def __repr__(self):
"""Returns the string representation of an instance of this class."""
return "DownloadCenter class instance for Commcell: '{0}'".format(
self._commcell_object.commserv_name
)
def _get_properties(self):
"""Get the properties of the download center."""
request_xml = """
<App_DCGetDataToCreatePackageReq getListOfUsers="1"
getListOfGroups="1" getCategories="1" getSubCategories="1"
getPlatforms="1" getDownloadTypes="1" getProductVersions="1"
getRecutNumbers="1" getVendors="1" getDownloadedPackageUsers="1"
packageId="1" getServerTypes="1"/>
"""
flag, response = self._cvpysdk_object.make_request(
'POST', self._services['GET_DC_DATA'], request_xml
)
if flag:
try:
self._response = response.json()
except ExpatError:
raise SDKException('DownloadCenter', '101', response.text)
else:
response_string = self._update_response_(response.text)
raise SDKException('Response', '101', response_string)
def _get_packages(self):
"""Gets the list of all the Active packages available at the download center."""
request_xml = """
<DM2ContentIndexing_CVSearchReq mode="2">
<searchProcessingInfo pageSize="1000000">
<queryParams param="ENABLE_DOWNLOADCENTER" value="true"/>
<queryParams param="GROUP_RESULTS_BY" value="PKG_ID"/>
<queryParams param="GROUP_LIMIT" value="50"/>
<queryParams param="GROUP_FACETS" value="true"/>
<queryParams param="GROUP_FLAT_RESULTS" value="false"/>
<queryParams param="SORTFIELD" value="VALID_FROM"/>
</searchProcessingInfo>
<advSearchGrp />
<facetRequests>
<facetRequest count="1" name="PKG_STATUS">
<stringParameter selected="1" name="0"/>
</facetRequest>
</facetRequests>
</DM2ContentIndexing_CVSearchReq>
"""
root = 'DM2ContentIndexing_CVDownloadCenterResp'
flag, response = self._cvpysdk_object.make_request(
'POST', self._services['SEARCH_PACKAGES'], request_xml
)
if flag:
try:
packages = response.json()['searchResult']['packages']
if isinstance(packages, dict):
packages = [packages]
for package in packages:
name = package['name'].lower()
self._packages[name] = {
'id': package['packageId'],
'description': package['description'],
'platforms': {}
}
platforms = package['platforms']
if isinstance(platforms, dict):
platforms = [platforms]
for platform in platforms:
platform_name = platform['name']
platform_id = platform['id']
download_type = platform['downloadType']['name']
if platform_name not in self._packages[name]['platforms']:
self._packages[name]['platforms'][platform_name] = {
'id': platform_id,
'download_type': [download_type]
}
else:
self._packages[name]['platforms'][platform_name][
'download_type'].append(download_type)
except ExpatError:
raise SDKException('DownloadCenter', '101', response.text)
else:
response_string = self._update_response_(response.text)
raise SDKException('Response', '101', response_string)
def _process_category_request(self, operation, name, description=None, new_name=None):
"""Executes the request on the server, and process the response received from the server.
Args:
operation (str) -- type of operation to be performed on the server
e.g:
add - to add a new category
delete - to delete an existing category
update - to update the details of an existing category
name (str) -- name of the category to perform the operation on
description (str) -- description for the category
default: None
new_name (str) -- new name to be set for the category
in case of ``update`` operation
default: None
Returns:
None - if the operation was performed successfully
Raises:
SDKException:
if failed to process the request
if failed to parse the response
"""
operations = {
'service': 'DC_ENTITY',
'root': 'App_DCSaveLookupEntityResp',
'error': 'Failed to %s the category.\nError: "{0}"' % (operation)
}
if operation == 'add':
operation_type = '1'
category_id = ''
elif operation == 'delete':
operation_type = '2'
category_id = self._categories[name]['id']
elif operation == 'update':
operation_type = '3'
category_id = self._categories[name]['id']
name = new_name
else:
raise SDKException('DownloadCenter', '102', 'Invalid Operation')
if description is None:
description = ''
request_xml = """
<App_DCSaveLookupEntityReq operation="{0}">
<entitiesToSave entityType="0" id="{1}" name="{2}" description="{3}"/>
</App_DCSaveLookupEntityReq>
""".format(operation_type, category_id, name, description)
flag, response = self._cvpysdk_object.make_request(
'POST', self._services[operations['service']], request_xml
)
if flag:
try:
response = xmltodict.parse(response.text)[operations['root']]
result = response['@result']
try:
category_id = response['entitiesToSave']['@id']
error_code = response['entitiesToSave']['errorDetail']['@errorCode']
error_message = response['entitiesToSave']['errorDetail']['@errorMessage']
except KeyError:
# for delete category request,
# entitiesToSave key is not returned in the response
# so initialize these values to None
category_id = error_code = error_message = None
if result == '3' and error_code != '0':
error_message = operations['error'].format(error_message)
raise SDKException('DownloadCenter', '102', error_message)
self.refresh()
except ExpatError:
raise SDKException('DownloadCenter', '101', response.text)
else:
response_string = self._update_response_(response.text)
raise SDKException('Response', '101', response_string)
def _process_sub_category_request(
self,
operation,
name,
category,
description=None,
new_name=None):
"""Executes the request on the server, and process the response received from the server.
Args:
operation (str) -- type of operation to be performed on the server
e.g:
add - to add a new sub category
delete - to delete an existing sub category from the specified category
update - to update the details of an existing sub category
name (str) -- name of the sub category to perform the operation on
category (str) -- category for the sub category
description (str) -- description for the sub category
default: None
new_name (str) -- new name to be set for the sub category
in case of ``update`` operation
default: None
Returns:
None - if the operation was performed successfully
Raises:
SDKException:
if failed to process the request
if failed to parse the response
"""
operations = {
'service': 'DC_SUB_CATEGORY',
'root': 'App_DCSaveSubCategoriesMsg',
'error': 'Failed to %s the sub category.\nError: "{0}"' % (operation)
}
if operation == 'add':
operation_type = '1'
sub_category_id = ''
elif operation == 'delete':
operation_type = '2'
sub_category_id = self._categories[category]['sub_categories'][name]['id']
elif operation == 'update':
operation_type = '3'
sub_category_id = self._categories[category]['sub_categories'][name]['id']
name = new_name
else:
raise SDKException('DownloadCenter', '102', 'Invalid Operation')
if description is None:
description = ''
request_xml = """
<App_DCSaveSubCategoriesMsg operation="{0}">
<subCategories id="{1}" name="{2}" description="{3}" categoryId="{4}"/>
</App_DCSaveSubCategoriesMsg>
""".format(
operation_type, sub_category_id, name, description, self._categories[category]['id']
)
flag, response = self._cvpysdk_object.make_request(
'POST', self._services[operations['service']], request_xml
)
if flag:
try:
response = xmltodict.parse(response.text)[operations['root']]
result = response['@result']
sub_category_id = response['subCategories']['@id']
error_code = response['subCategories']['errorDetail']['@errorCode']
error_message = response['subCategories']['errorDetail']['@errorMessage']
if result == '3' and error_code != '0':
error_message = operations['error'].format(error_message)
raise SDKException('DownloadCenter', '102', error_message)
self.refresh()
except ExpatError:
raise SDKException('DownloadCenter', '101', response.text)
else:
response_string = self._update_response_(response.text)
raise SDKException('Response', '101', response_string)
@property
def product_versions(self):
"""Return the versions of product available at Download Center."""
if not self._product_versions:
product_versions = self._response['productVersions']
if isinstance(product_versions, dict):
product_versions = [product_versions]
for product_version in product_versions:
self._product_versions[product_version['@name']] = {
'id': product_version['@id'],
'entity_type': product_version['@entityType']
}
return list(self._product_versions.keys())
@property
def servers_for_browse(self):
"""Returns the servers available for browse at Download Center."""
if not self._servers_for_browse:
servers_for_browse = self._response['serversForBrowse']
if isinstance(servers_for_browse, dict):
servers_for_browse = [servers_for_browse]
for server_for_browse in servers_for_browse:
self._servers_for_browse[server_for_browse['@name']] = {
'id': server_for_browse['@id'],
'internal_name': server_for_browse['@internalName'],
'entity_type': server_for_browse['@entityType'],
'attribute': server_for_browse['@attribute']
}
return list(self._servers_for_browse.keys())
@property
def error_detail(self):
"""Returns the error details."""
return self._response['errorDetail']
@property
def users_and_groups(self):
"""Returns the Users and User Groups available at Download Center."""
if not self._users_and_groups:
users_and_groups = self._response['usersAndGroups']
if isinstance(users_and_groups, dict):
users_and_groups = [users_and_groups]
for user_and_group in self._response['usersAndGroups']:
self._users_and_groups[user_and_group['@name']] = {
'id': user_and_group['@id'],
'provider_id': user_and_group['@providerId'],
'guid': user_and_group['@guid'],
'type': user_and_group['@type'],
'service_type': user_and_group['@serviceType']
}
return list(self._users_and_groups.keys())
@property
def categories(self):
"""Returns the categories of products available at Download Center."""
if not self._categories:
categories = self._response['categories']
if isinstance(categories, dict):
categories = [categories]
for category in categories:
category_id = category['@id']
temp = {}
sub_categories = self._response['subCategories']
if isinstance(sub_categories, dict):
sub_categories = [sub_categories]
for sub_category in sub_categories:
cat_id = sub_category['@categoryId']
if cat_id == category_id:
temp[sub_category['@name']] = {
'id': sub_category['@id'],
'description': sub_category['@description'],
'entity_type': sub_category['@entityType'],
'attribute': sub_category['@attribute']
}
self._categories[category['@name']] = {
'id': category_id,
'description': category['@description'],
'entity_type': category['@entityType'],
'attribute': category['@attribute'],
'sub_categories': temp
}
return list(self._categories)
@property
def download_types(self):
"""Returns the types of packages available for download at Download Center."""
if not self._download_types:
download_types = self._response['downloadTypes']
if isinstance(download_types, dict):
download_types = [download_types]
for download_type in download_types:
self._download_types[download_type['@name']] = {
'id': download_type['@id'],
'entity_type': download_type['@entityType']
}
return list(self._download_types.keys())
@property
def vendors(self):
"""Returns the vendors available at Download Center."""
if not self._vendors:
vendors = self._response['vendors']
if isinstance(vendors, dict):
vendors = [vendors]
for vendor in vendors:
self._vendors[vendor['@name']] = {
'id': vendor['@id'],
'entity_type': vendor['@entityType']
}
return list(self._vendors.keys())
@property
def platforms(self):
"""Returns the platforms supported for packages at Download Center."""
if not self._platforms:
platforms = self._response['platforms']
if isinstance(platforms, dict):
platforms = [platforms]
for platform in platforms:
self._platforms[platform['@name']] = {
'id': platform['@id'],
'entity_type': platform['@entityType'],
'architecture': platform['@architectureName']
}
return list(self._platforms.keys())
@property
def packages(self):
"""Returns the packages available for download at Download Center."""
if not self._packages:
self._get_packages()
return list(self._packages.keys())
def has_package(self, package):
"""Checks if a package with the given name already exists at Download Center or not.
Args:
package (str) -- name of the package to check
Returns:
bool - boolean specifying whether the package exists or not
"""
return self.packages and package.lower() in self.packages
def sub_categories(self, category):
"""Returns the sub categories available for the specified category.
Args:
category (str) -- name of the category to get the sub categories of
Returns:
list - list of sub categories available for the given category
Raises:
SDKException:
if category does not exist
"""
if category not in self.categories:
raise SDKException('DownloadCenter', '103')
return list(self._categories[category]['sub_categories'].keys())
def get_package_details(self, package):
"""Returns the details of the package, like the package description, platforms, etc.
Args:
package (str) -- name of the package to get the details of
Returns:
dict - dictionary consisting of the details of the package
Raises:
SDKException:
if package does not exist
"""
if not self.has_package(package):
raise SDKException('DownloadCenter', '106')
package = package.lower()
package_detail = self._packages[package]
output = {
'name': package,
'description': package_detail['description'],
'platforms': {}
}
platforms = package_detail['platforms']
for platform in platforms:
output['platforms'][platform] = platforms[platform]['download_type']
return output
def add_category(self, name, description=None):
"""Adds a new category with the given name, and description.
Args:
name (str) -- name of the category to add
description (str) -- description for the category (optional)
default: None
Returns:
None - if the category was added successfully
Raises:
SDKException:
if category already exists
if failed to add the category
"""
if name in self.categories:
raise SDKException('DownloadCenter', '104')
self._process_category_request('add', name, description)
def update_category(self, name, new_name, description=None):
"""Updates the name and description of the category with the given name.
Args:
name (str) -- name of the existing category to update
new_name (str) -- new name for the category
description (str) -- description for the category (optional)
default: None
Returns:
None - if the category information was updated successfully
Raises:
SDKException:
if no category exists with the given name
if category already exists with the new name specified
if failed to update the category
"""
if name not in self.categories:
raise SDKException('DownloadCenter', '108')
if new_name in self.categories:
raise SDKException('DownloadCenter', '104')
self._process_category_request('update', name, description, new_name)
def delete_category(self, name):
"""Deletes the category with the given name.
Args:
name (str) -- name of the category to delete
Returns:
None - if the category was deleted successfully
Raises:
SDKException:
if category does not exists
if failed to delete the category
"""
if name not in self.categories:
raise SDKException('DownloadCenter', '108')
self._process_category_request('delete', name)
def add_sub_category(self, name, category, description=None):
"""Adds a new sub category with the given name, and description to the specified category.
Args:
name (str) -- name of the sub category to add
category (str) -- name of the category to add the sub category to
description (str) -- description for the sub category (optional)
default: None
Returns:
None - if the sub category was added successfully
Raises:
SDKException:
if category does not exist
if sub category already exists
if failed to add the sub category
"""
if name in self.sub_categories(category):
raise SDKException('DownloadCenter', '105')
self._process_sub_category_request('add', name, category, description)
def update_sub_category(self, name, category, new_name, description=None):
"""Updates the name and description of the sub category with the given name and category.
Args:
name (str) -- name of the sub category to update the details of
category (str) -- name of the category to update the sub category of
new_name (str) -- new name for the sub category
description (str) -- description for the sub category (optional)
default: None
Returns:
None - if the sub category information was updated successfully
Raises:
SDKException:
if no sub category exists with the given name
if sub category already exists with the new name specified
if failed to update the sub category
"""
if name not in self.sub_categories(category):
raise SDKException('DownloadCenter', '109')
if new_name in self.sub_categories(category):
raise SDKException('DownloadCenter', '105')
self._process_sub_category_request('update', name, category, description, new_name)
def delete_sub_category(self, name, category):
"""Deletes the sub category from the category with the given name.
Args:
name (str) -- name of the sub category to delete
category (str) -- name of the category to delete the sub category from
Returns:
None - if the sub category was deleted successfully
Raises:
SDKException:
if sub category does not exist
if failed to delete the sub category
"""
if name not in self.sub_categories(category):
raise SDKException('DownloadCenter', '109')
self._process_sub_category_request('delete', name, category)
def upload_package(self, package, category, version, platform_download_locations, **kwargs):
"""Uploads the given package to Download Center.
Args:
package (str) -- name of the package to upload
category (str) -- category to upload the package for
version (str) -- product version for package to upload
platform_download_locations (list) -- list consisting of dictionaries
where each dictionary contains the values for the platform, download type, and
location of the file
e.g.:
[
{
'platform': 'Windows-x64',
'download_type': 'Exe',
'location': 'C:\\location1'
}, {
'platform': 'Windows-x64',
'download_type': 'Script',
'location': 'C:\\location2'
}, {
'platform': 'Windows-x86',
'download_type': 'Exe',
'location': 'C:\\location3'
}, {
'platform': 'Windows-x86',
'download_type': 'Script',
'location': 'C:\\location4'
}
]
**kwargs:
valid_from (str) -- date from which the package should be valid
if the value is not specified, then current date is taken as it's value
format: DD/MM/YYYY
description (str) -- description of the package
readme_location (str) -- location of the readme file
readme file should have one of the following extensions
[**.txt**, **.pdf**, **.doc**, **.docx**]
sub_category (str) -- sub category to associate the package with
vendor (str) -- vendor / distributor of the package
valid_to (str) -- date till which the package should be valid
format: DD/MM/YYYY
repository (str) -- name of the repository to add the package to
if this value is not defined, the first repository will be taken by default
visible_to (list) -- list of users, the package should be visible to
not_visible_to (list) -- users, the package should not be visible to
early_preview_users (list) -- list of users, the package should be
visible to before release
Returns:
None - if the package was uploaded successfully to Download Center
Raises:
SDKException:
if package with given name already exists
if category does not exists at Download Center
if version is not supported at Download Center
if platform is not supported at Download Center
if download type is not supported at Download Center
if sub category not present for the given category
if failed to upload the package
if error returned by the server
if response was not success
"""
if self.has_package(package):
raise SDKException('DownloadCenter', '114')
if category not in self.categories:
raise SDKException(
'DownloadCenter', '103', 'Available categories: {0}'.format(self.categories)
)
if version not in self.product_versions:
raise SDKException(
'DownloadCenter', '115', 'Available versions: {0}'.format(self.product_versions)
)
platforms = []
readme_location = kwargs.get('readme_location', '')
readme_file_extensions = ['.txt', '.pdf', '.doc', '.docx']
if readme_location:
if os.path.splitext(readme_location)[1] not in readme_file_extensions:
raise SDKException('DownloadCenter', '118')
del readme_file_extensions
for platform_dl_loc in platform_download_locations:
platform = platform_dl_loc['platform']
download_type = platform_dl_loc['download_type']
location = platform_dl_loc['location']
if platform not in self.platforms:
raise SDKException(
'DownloadCenter', '116', 'Available platforms: {0}'.format(self.platforms)
)
if download_type not in self.download_types:
raise SDKException(
'DownloadCenter',
'117',
'Available download types: {0}'.format(self.download_types)
)
package_repository = kwargs.get('repository', self.servers_for_browse[0])
package_repository_id = self._servers_for_browse[package_repository]['id']
package_repository_name = self._servers_for_browse[package_repository]['internal_name']
temp = {
"@name": platform,
"@readMeLocation": readme_location,
"@location": location,
"@id": self._platforms[platform]['id'],
"downloadType": {
"@name": download_type,
"@id": self._download_types[download_type]['id']
},
'pkgRepository': {
'@repositoryId': package_repository_id,
'@respositoryName': package_repository_name
},
'@size': 186646528
}
platforms.append(temp)
del platform
del download_type
del location
del temp
del platform_download_locations
valid_from = kwargs.get('valid_from', time.strftime('%d/%m/%Y', time.localtime()))
valid_from = int(time.mktime(time.strptime(valid_from, '%d/%m/%Y')))
valid_to = kwargs.get('valid_to', '')
if valid_to:
valid_to = int(time.mktime(time.strptime(valid_from, '%d/%m/%Y')))
sub_category = {
"@entityType": 1,
"@categoryId": self._categories[category]['id']
}
if 'sub_category' in kwargs:
sub_category_name = kwargs['sub_category']
sub_categories = self.sub_categories(category)
if sub_category_name in sub_categories:
sub_category["@id"] = self._categories[category][
'sub_categories'][sub_category_name]['id']
else:
raise SDKException(
'DownloadCenter', '109', 'Available Sub Categories: {0}'.format(sub_categories)
)
del sub_categories
vendor = kwargs.get('vendor', '')
if vendor and vendor in self.vendors:
vendor = self._vendors[vendor]['id']
visible_to = []
not_visible_to = []
early_preview_users = []
for user in kwargs.get('visible_to', []):
if user in self.users_and_groups:
temp = {
'@name': user,
'@guid': self._users_and_groups[user]['guid'],
'@type': self._users_and_groups[user]['type']
}
visible_to.append(temp)
for user in kwargs.get('not_visible_to', []):
if user in self.users_and_groups:
temp = {
'@name': user,
'@guid': self._users_and_groups[user]['guid'],
'@type': self._users_and_groups[user]['type']
}
not_visible_to.append(temp)
for user in kwargs.get('early_preview_users', []):
if user in self.users_and_groups:
temp = {
'@name': user,
'@guid': self._users_and_groups[user]['guid'],
'@type': self._users_and_groups[user]['type']
}
early_preview_users.append(temp)
request_json = {
"App_DCPackage": {
"@name": package,
"@description": kwargs.get('description', ''),
"@validFrom": valid_from,
"@validTo": valid_to,
"@rank": kwargs.get('rank', 0),
"category": {
"@entityType": 0,
"@id": self._categories[category]['id']
},
"subCategory": sub_category,
"platforms": platforms,
"productVersion": {
"entityType": 3,
"id": self._product_versions[version]['id']
},
"vendor": {
"entityType": 6,
"id": vendor
},
"recutNumber": {
"entityType": 4
},
"visibleTo": visible_to,
"notVisibleTo": not_visible_to,
"earlyPreviewUsers": early_preview_users,
}
}
xml = xmltodict.unparse(request_json)
xml = xml[xml.find('<App_'):]
flag, response = self._cvpysdk_object.make_request(
'POST', self._services['UPLOAD_PACKAGE'], xml
)
self.refresh()
if flag:
response = xmltodict.parse(response.text)['App_DCPackage']
error_code = response['errorDetail']['@errorCode']
if error_code != '0':
error_message = response['errorDetail']['@errorMessage']
raise SDKException('DownloadCenter', '119', 'Error: {0}'.format(error_message))
else:
response_string = self._update_response_(response.text)
raise SDKException('Response', '101', response_string)
def download_package(self, package, download_location, platform=None, download_type=None):
"""Downloads the given package from Download Center to the path specified.
Args:
package (str) -- name of the pacakge to be downloaded
download_location (str) -- path on local machine to download the package at
platform (str) -- platform to download the package for
to be provided only if the package is added for multiple platforms
default: None
download_type (str) -- type of package to be downloaded
to be provided only if multiple download types are present for single platform
default: None
Returns:
str - path on local machine where the file has been downloaded
Raises:
SDKException:
if package does not exist
if platform not given:
in case of multiple platforms
if platform given does not exists in the list of supported platforms
if download type is not specified:
if case of multiple download types for the selected platform
if download type given does not exists in the list of download types available
if error returned by the server
if response was not success
"""
# get the id of the package, if it is a valid package
if not self.has_package(package):
raise SDKException('DownloadCenter', '106')
else:
package = package.lower()
package_id = self._packages[package]['id']
def get_platform_id(package, platform):
"""Checks if the platform is valid or not, and returns the platform id.
If platform is set to None, gets the platform from the list of platforms,
and the platform id.
Args:
package (str) -- name of the package to check the platform for
platform (str) -- name of the platform to get the id of
Returns:
(str, str) - tuple consisting of the platform name as the first,
and platform id as the second value
Raises:
SDKException:
if platform is not given, and multiple platforms exists for the package
if platform specified is not supported for the package
"""
platforms = self._packages[package]['platforms']
# check if the package has a single platform only, in case platform is not given
if platform is None:
# raise exception if multiple platforms exist for the package
if len(platforms.keys()) > 1:
raise SDKException('DownloadCenter', '110')
# get the platform name and id, if it's a single platform
else:
platform = list(platforms.keys())[0]
platform_id = platforms[platform]['id']
# raise exception if the platform does not exists in the list of supported platforms,
# when it is given
elif platform not in platforms:
raise SDKException('DownloadCenter', '112')
# get the id of the platform,
# when it's given and exists in the list of supported platforms
else:
platform_id = platforms[platform]['id']
return platform, platform_id
def get_download_type(package, platform, download_type):
"""Checks if the download type for the given package and platform is valid or not.
If download type is set to None, gets the download type from the list of download
types availalble for the given package and platform.
Args:
package (str) -- name of the package to get the download type for
platform (str) -- name of the platform to get the download type of
download_type (str) -- download type to be validated
Returns:
str - name of the download type
Raises:
SDKException:
if download type is not given, and multiple download types exists
if download type specified is not available for the package
"""
download_types = self._packages[package]['platforms'][platform]['download_type']
# check if the package has a single download type only,
# in case download type is not given
if download_type is None:
# raise exception if multiple download types exist for the package and the platform
if len(download_types) > 1:
raise SDKException('DownloadCenter', '111')
# get the download type name, if it's a single download type for the given platform
else:
download_type = download_types[0]
# raise exception if the download type does not exists in the list, when it is given
elif download_type not in download_types:
raise SDKException('DownloadCenter', '113')
# use the download type given by the user
else:
pass
return download_type
platform, platform_id = get_platform_id(package, platform)
download_type = get_download_type(package, platform, download_type)
if not os.path.exists(download_location):
try:
os.makedirs(download_location)
except FileExistsError:
pass
request_id = ''
file_name = None
# ID: 3 is static for Download Center, and has the value "Package"
# ID: 2, needs to provide the package id as the value for "name"
# ID: 9, needs to provide the platform id as the value for "name"
# ID: 11, needs to provide the download tyoe as the value for "name"
# ID: 10 is static for Streamed downloads
request_xml = '''
<DM2ContentIndexing_OpenFileReq requestId="{3}">
<fileParams id="3" name="Package"/>
<fileParams id="2" name="{0}"/>
<fileParams id="9" name="{1}"/>
<fileParams id="11" name="{2}"/>
<fileParams id="10" name="Streamed"/>
</DM2ContentIndexing_OpenFileReq>
'''
# execute the request to get the details like file name, and request id
flag, response = self._cvpysdk_object.make_request(
'POST', self._services['DOWNLOAD_PACKAGE'], request_xml.format(
package_id, platform_id, download_type, request_id
)
)
if flag:
error_list = response.json()['errList']
file_content = response.json()['fileContent']
if error_list:
raise SDKException('DownloadCenter', '107', 'Error: {0}'.format(error_list))
file_name = file_content.get('fileName', file_name)
request_id = file_content['requestId']
# full path of the file on local machine to be downloaded
download_path = os.path.join(download_location, file_name)
# execute request to get the stream of content
# using request id returned in the previous response
flag1, response1 = self._cvpysdk_object.make_request(
'POST',
self._services['DOWNLOAD_VIA_STREAM'],
request_xml.format(package_id, platform_id, download_type, request_id),
stream=True
)
# download chunks of 1MB each
chunk_size = 1024 ** 2
if flag1:
with open(download_path, "wb") as file_pointer:
for content in response1.iter_content(chunk_size=chunk_size):
file_pointer.write(content)
else:
response_string = self._update_response_(response1.text)
raise SDKException('Response', '101', response_string)
else:
response_string = self._update_response_(response.text)
raise SDKException('Response', '101', response_string)
return download_path
def delete_package(self, package):
"""Deletes the package from Download Center.
Args:
package (str) -- name of the package to be deleted
Returns:
None - if the package was deleted successfully
Raises:
SDKException:
if no package exists with the given name
if failed to delete the package
if response is not success
"""
if not self.has_package(package):
raise SDKException('DownloadCenter', '106')
else:
package = package.lower()
package_id = self._packages[package]['id']
flag, response = self._cvpysdk_object.make_request(
'GET', self._services['DELETE_PACKAGE'] % package_id
)
self.refresh()
if flag:
response = xmltodict.parse(response.text)['DM2ContentIndexing_CVDownloadCenterResp']
if 'errList' in response:
error_code = response['errList']['@errorCode']
if error_code != '0':
error_message = response['errList']['@errLogMessage']
raise SDKException('DownloadCenter', '119', 'Error: {0}'.format(error_message))
else:
response_string = self._update_response_(response.text)
raise SDKException('Response', '101', response_string)
def refresh(self):
"""Refresh the properties of the DownloadCenter."""
self._get_properties()
self._product_versions = {}
self._servers_for_browse = {}
self._users_and_groups = {}
self._categories = {}
self._download_types = {}
self._vendors = {}
self._platforms = {}
self._packages = {}
self._get_packages()
Classes
class DownloadCenter (commcell_object)
-
Class for doing operations on Download Center like upload or download product.
Initializes an instance of the DownloadCenter class.
Args
commcell_object (object) – instance of the Commcell class
Returns
object - instance of the DownloadCenter class
Expand source code Browse git
class DownloadCenter(object): """Class for doing operations on Download Center like upload or download product.""" def __init__(self, commcell_object): """Initializes an instance of the DownloadCenter class. Args: commcell_object (object) -- instance of the Commcell class Returns: object - instance of the DownloadCenter class """ self._commcell_object = commcell_object self._cvpysdk_object = commcell_object._cvpysdk_object self._services = commcell_object._services self._update_response_ = commcell_object._update_response_ self._response = None self.refresh() def __repr__(self): """Returns the string representation of an instance of this class.""" return "DownloadCenter class instance for Commcell: '{0}'".format( self._commcell_object.commserv_name ) def _get_properties(self): """Get the properties of the download center.""" request_xml = """ <App_DCGetDataToCreatePackageReq getListOfUsers="1" getListOfGroups="1" getCategories="1" getSubCategories="1" getPlatforms="1" getDownloadTypes="1" getProductVersions="1" getRecutNumbers="1" getVendors="1" getDownloadedPackageUsers="1" packageId="1" getServerTypes="1"/> """ flag, response = self._cvpysdk_object.make_request( 'POST', self._services['GET_DC_DATA'], request_xml ) if flag: try: self._response = response.json() except ExpatError: raise SDKException('DownloadCenter', '101', response.text) else: response_string = self._update_response_(response.text) raise SDKException('Response', '101', response_string) def _get_packages(self): """Gets the list of all the Active packages available at the download center.""" request_xml = """ <DM2ContentIndexing_CVSearchReq mode="2"> <searchProcessingInfo pageSize="1000000"> <queryParams param="ENABLE_DOWNLOADCENTER" value="true"/> <queryParams param="GROUP_RESULTS_BY" value="PKG_ID"/> <queryParams param="GROUP_LIMIT" value="50"/> <queryParams param="GROUP_FACETS" value="true"/> <queryParams param="GROUP_FLAT_RESULTS" value="false"/> <queryParams param="SORTFIELD" value="VALID_FROM"/> </searchProcessingInfo> <advSearchGrp /> <facetRequests> <facetRequest count="1" name="PKG_STATUS"> <stringParameter selected="1" name="0"/> </facetRequest> </facetRequests> </DM2ContentIndexing_CVSearchReq> """ root = 'DM2ContentIndexing_CVDownloadCenterResp' flag, response = self._cvpysdk_object.make_request( 'POST', self._services['SEARCH_PACKAGES'], request_xml ) if flag: try: packages = response.json()['searchResult']['packages'] if isinstance(packages, dict): packages = [packages] for package in packages: name = package['name'].lower() self._packages[name] = { 'id': package['packageId'], 'description': package['description'], 'platforms': {} } platforms = package['platforms'] if isinstance(platforms, dict): platforms = [platforms] for platform in platforms: platform_name = platform['name'] platform_id = platform['id'] download_type = platform['downloadType']['name'] if platform_name not in self._packages[name]['platforms']: self._packages[name]['platforms'][platform_name] = { 'id': platform_id, 'download_type': [download_type] } else: self._packages[name]['platforms'][platform_name][ 'download_type'].append(download_type) except ExpatError: raise SDKException('DownloadCenter', '101', response.text) else: response_string = self._update_response_(response.text) raise SDKException('Response', '101', response_string) def _process_category_request(self, operation, name, description=None, new_name=None): """Executes the request on the server, and process the response received from the server. Args: operation (str) -- type of operation to be performed on the server e.g: add - to add a new category delete - to delete an existing category update - to update the details of an existing category name (str) -- name of the category to perform the operation on description (str) -- description for the category default: None new_name (str) -- new name to be set for the category in case of ``update`` operation default: None Returns: None - if the operation was performed successfully Raises: SDKException: if failed to process the request if failed to parse the response """ operations = { 'service': 'DC_ENTITY', 'root': 'App_DCSaveLookupEntityResp', 'error': 'Failed to %s the category.\nError: "{0}"' % (operation) } if operation == 'add': operation_type = '1' category_id = '' elif operation == 'delete': operation_type = '2' category_id = self._categories[name]['id'] elif operation == 'update': operation_type = '3' category_id = self._categories[name]['id'] name = new_name else: raise SDKException('DownloadCenter', '102', 'Invalid Operation') if description is None: description = '' request_xml = """ <App_DCSaveLookupEntityReq operation="{0}"> <entitiesToSave entityType="0" id="{1}" name="{2}" description="{3}"/> </App_DCSaveLookupEntityReq> """.format(operation_type, category_id, name, description) flag, response = self._cvpysdk_object.make_request( 'POST', self._services[operations['service']], request_xml ) if flag: try: response = xmltodict.parse(response.text)[operations['root']] result = response['@result'] try: category_id = response['entitiesToSave']['@id'] error_code = response['entitiesToSave']['errorDetail']['@errorCode'] error_message = response['entitiesToSave']['errorDetail']['@errorMessage'] except KeyError: # for delete category request, # entitiesToSave key is not returned in the response # so initialize these values to None category_id = error_code = error_message = None if result == '3' and error_code != '0': error_message = operations['error'].format(error_message) raise SDKException('DownloadCenter', '102', error_message) self.refresh() except ExpatError: raise SDKException('DownloadCenter', '101', response.text) else: response_string = self._update_response_(response.text) raise SDKException('Response', '101', response_string) def _process_sub_category_request( self, operation, name, category, description=None, new_name=None): """Executes the request on the server, and process the response received from the server. Args: operation (str) -- type of operation to be performed on the server e.g: add - to add a new sub category delete - to delete an existing sub category from the specified category update - to update the details of an existing sub category name (str) -- name of the sub category to perform the operation on category (str) -- category for the sub category description (str) -- description for the sub category default: None new_name (str) -- new name to be set for the sub category in case of ``update`` operation default: None Returns: None - if the operation was performed successfully Raises: SDKException: if failed to process the request if failed to parse the response """ operations = { 'service': 'DC_SUB_CATEGORY', 'root': 'App_DCSaveSubCategoriesMsg', 'error': 'Failed to %s the sub category.\nError: "{0}"' % (operation) } if operation == 'add': operation_type = '1' sub_category_id = '' elif operation == 'delete': operation_type = '2' sub_category_id = self._categories[category]['sub_categories'][name]['id'] elif operation == 'update': operation_type = '3' sub_category_id = self._categories[category]['sub_categories'][name]['id'] name = new_name else: raise SDKException('DownloadCenter', '102', 'Invalid Operation') if description is None: description = '' request_xml = """ <App_DCSaveSubCategoriesMsg operation="{0}"> <subCategories id="{1}" name="{2}" description="{3}" categoryId="{4}"/> </App_DCSaveSubCategoriesMsg> """.format( operation_type, sub_category_id, name, description, self._categories[category]['id'] ) flag, response = self._cvpysdk_object.make_request( 'POST', self._services[operations['service']], request_xml ) if flag: try: response = xmltodict.parse(response.text)[operations['root']] result = response['@result'] sub_category_id = response['subCategories']['@id'] error_code = response['subCategories']['errorDetail']['@errorCode'] error_message = response['subCategories']['errorDetail']['@errorMessage'] if result == '3' and error_code != '0': error_message = operations['error'].format(error_message) raise SDKException('DownloadCenter', '102', error_message) self.refresh() except ExpatError: raise SDKException('DownloadCenter', '101', response.text) else: response_string = self._update_response_(response.text) raise SDKException('Response', '101', response_string) @property def product_versions(self): """Return the versions of product available at Download Center.""" if not self._product_versions: product_versions = self._response['productVersions'] if isinstance(product_versions, dict): product_versions = [product_versions] for product_version in product_versions: self._product_versions[product_version['@name']] = { 'id': product_version['@id'], 'entity_type': product_version['@entityType'] } return list(self._product_versions.keys()) @property def servers_for_browse(self): """Returns the servers available for browse at Download Center.""" if not self._servers_for_browse: servers_for_browse = self._response['serversForBrowse'] if isinstance(servers_for_browse, dict): servers_for_browse = [servers_for_browse] for server_for_browse in servers_for_browse: self._servers_for_browse[server_for_browse['@name']] = { 'id': server_for_browse['@id'], 'internal_name': server_for_browse['@internalName'], 'entity_type': server_for_browse['@entityType'], 'attribute': server_for_browse['@attribute'] } return list(self._servers_for_browse.keys()) @property def error_detail(self): """Returns the error details.""" return self._response['errorDetail'] @property def users_and_groups(self): """Returns the Users and User Groups available at Download Center.""" if not self._users_and_groups: users_and_groups = self._response['usersAndGroups'] if isinstance(users_and_groups, dict): users_and_groups = [users_and_groups] for user_and_group in self._response['usersAndGroups']: self._users_and_groups[user_and_group['@name']] = { 'id': user_and_group['@id'], 'provider_id': user_and_group['@providerId'], 'guid': user_and_group['@guid'], 'type': user_and_group['@type'], 'service_type': user_and_group['@serviceType'] } return list(self._users_and_groups.keys()) @property def categories(self): """Returns the categories of products available at Download Center.""" if not self._categories: categories = self._response['categories'] if isinstance(categories, dict): categories = [categories] for category in categories: category_id = category['@id'] temp = {} sub_categories = self._response['subCategories'] if isinstance(sub_categories, dict): sub_categories = [sub_categories] for sub_category in sub_categories: cat_id = sub_category['@categoryId'] if cat_id == category_id: temp[sub_category['@name']] = { 'id': sub_category['@id'], 'description': sub_category['@description'], 'entity_type': sub_category['@entityType'], 'attribute': sub_category['@attribute'] } self._categories[category['@name']] = { 'id': category_id, 'description': category['@description'], 'entity_type': category['@entityType'], 'attribute': category['@attribute'], 'sub_categories': temp } return list(self._categories) @property def download_types(self): """Returns the types of packages available for download at Download Center.""" if not self._download_types: download_types = self._response['downloadTypes'] if isinstance(download_types, dict): download_types = [download_types] for download_type in download_types: self._download_types[download_type['@name']] = { 'id': download_type['@id'], 'entity_type': download_type['@entityType'] } return list(self._download_types.keys()) @property def vendors(self): """Returns the vendors available at Download Center.""" if not self._vendors: vendors = self._response['vendors'] if isinstance(vendors, dict): vendors = [vendors] for vendor in vendors: self._vendors[vendor['@name']] = { 'id': vendor['@id'], 'entity_type': vendor['@entityType'] } return list(self._vendors.keys()) @property def platforms(self): """Returns the platforms supported for packages at Download Center.""" if not self._platforms: platforms = self._response['platforms'] if isinstance(platforms, dict): platforms = [platforms] for platform in platforms: self._platforms[platform['@name']] = { 'id': platform['@id'], 'entity_type': platform['@entityType'], 'architecture': platform['@architectureName'] } return list(self._platforms.keys()) @property def packages(self): """Returns the packages available for download at Download Center.""" if not self._packages: self._get_packages() return list(self._packages.keys()) def has_package(self, package): """Checks if a package with the given name already exists at Download Center or not. Args: package (str) -- name of the package to check Returns: bool - boolean specifying whether the package exists or not """ return self.packages and package.lower() in self.packages def sub_categories(self, category): """Returns the sub categories available for the specified category. Args: category (str) -- name of the category to get the sub categories of Returns: list - list of sub categories available for the given category Raises: SDKException: if category does not exist """ if category not in self.categories: raise SDKException('DownloadCenter', '103') return list(self._categories[category]['sub_categories'].keys()) def get_package_details(self, package): """Returns the details of the package, like the package description, platforms, etc. Args: package (str) -- name of the package to get the details of Returns: dict - dictionary consisting of the details of the package Raises: SDKException: if package does not exist """ if not self.has_package(package): raise SDKException('DownloadCenter', '106') package = package.lower() package_detail = self._packages[package] output = { 'name': package, 'description': package_detail['description'], 'platforms': {} } platforms = package_detail['platforms'] for platform in platforms: output['platforms'][platform] = platforms[platform]['download_type'] return output def add_category(self, name, description=None): """Adds a new category with the given name, and description. Args: name (str) -- name of the category to add description (str) -- description for the category (optional) default: None Returns: None - if the category was added successfully Raises: SDKException: if category already exists if failed to add the category """ if name in self.categories: raise SDKException('DownloadCenter', '104') self._process_category_request('add', name, description) def update_category(self, name, new_name, description=None): """Updates the name and description of the category with the given name. Args: name (str) -- name of the existing category to update new_name (str) -- new name for the category description (str) -- description for the category (optional) default: None Returns: None - if the category information was updated successfully Raises: SDKException: if no category exists with the given name if category already exists with the new name specified if failed to update the category """ if name not in self.categories: raise SDKException('DownloadCenter', '108') if new_name in self.categories: raise SDKException('DownloadCenter', '104') self._process_category_request('update', name, description, new_name) def delete_category(self, name): """Deletes the category with the given name. Args: name (str) -- name of the category to delete Returns: None - if the category was deleted successfully Raises: SDKException: if category does not exists if failed to delete the category """ if name not in self.categories: raise SDKException('DownloadCenter', '108') self._process_category_request('delete', name) def add_sub_category(self, name, category, description=None): """Adds a new sub category with the given name, and description to the specified category. Args: name (str) -- name of the sub category to add category (str) -- name of the category to add the sub category to description (str) -- description for the sub category (optional) default: None Returns: None - if the sub category was added successfully Raises: SDKException: if category does not exist if sub category already exists if failed to add the sub category """ if name in self.sub_categories(category): raise SDKException('DownloadCenter', '105') self._process_sub_category_request('add', name, category, description) def update_sub_category(self, name, category, new_name, description=None): """Updates the name and description of the sub category with the given name and category. Args: name (str) -- name of the sub category to update the details of category (str) -- name of the category to update the sub category of new_name (str) -- new name for the sub category description (str) -- description for the sub category (optional) default: None Returns: None - if the sub category information was updated successfully Raises: SDKException: if no sub category exists with the given name if sub category already exists with the new name specified if failed to update the sub category """ if name not in self.sub_categories(category): raise SDKException('DownloadCenter', '109') if new_name in self.sub_categories(category): raise SDKException('DownloadCenter', '105') self._process_sub_category_request('update', name, category, description, new_name) def delete_sub_category(self, name, category): """Deletes the sub category from the category with the given name. Args: name (str) -- name of the sub category to delete category (str) -- name of the category to delete the sub category from Returns: None - if the sub category was deleted successfully Raises: SDKException: if sub category does not exist if failed to delete the sub category """ if name not in self.sub_categories(category): raise SDKException('DownloadCenter', '109') self._process_sub_category_request('delete', name, category) def upload_package(self, package, category, version, platform_download_locations, **kwargs): """Uploads the given package to Download Center. Args: package (str) -- name of the package to upload category (str) -- category to upload the package for version (str) -- product version for package to upload platform_download_locations (list) -- list consisting of dictionaries where each dictionary contains the values for the platform, download type, and location of the file e.g.: [ { 'platform': 'Windows-x64', 'download_type': 'Exe', 'location': 'C:\\location1' }, { 'platform': 'Windows-x64', 'download_type': 'Script', 'location': 'C:\\location2' }, { 'platform': 'Windows-x86', 'download_type': 'Exe', 'location': 'C:\\location3' }, { 'platform': 'Windows-x86', 'download_type': 'Script', 'location': 'C:\\location4' } ] **kwargs: valid_from (str) -- date from which the package should be valid if the value is not specified, then current date is taken as it's value format: DD/MM/YYYY description (str) -- description of the package readme_location (str) -- location of the readme file readme file should have one of the following extensions [**.txt**, **.pdf**, **.doc**, **.docx**] sub_category (str) -- sub category to associate the package with vendor (str) -- vendor / distributor of the package valid_to (str) -- date till which the package should be valid format: DD/MM/YYYY repository (str) -- name of the repository to add the package to if this value is not defined, the first repository will be taken by default visible_to (list) -- list of users, the package should be visible to not_visible_to (list) -- users, the package should not be visible to early_preview_users (list) -- list of users, the package should be visible to before release Returns: None - if the package was uploaded successfully to Download Center Raises: SDKException: if package with given name already exists if category does not exists at Download Center if version is not supported at Download Center if platform is not supported at Download Center if download type is not supported at Download Center if sub category not present for the given category if failed to upload the package if error returned by the server if response was not success """ if self.has_package(package): raise SDKException('DownloadCenter', '114') if category not in self.categories: raise SDKException( 'DownloadCenter', '103', 'Available categories: {0}'.format(self.categories) ) if version not in self.product_versions: raise SDKException( 'DownloadCenter', '115', 'Available versions: {0}'.format(self.product_versions) ) platforms = [] readme_location = kwargs.get('readme_location', '') readme_file_extensions = ['.txt', '.pdf', '.doc', '.docx'] if readme_location: if os.path.splitext(readme_location)[1] not in readme_file_extensions: raise SDKException('DownloadCenter', '118') del readme_file_extensions for platform_dl_loc in platform_download_locations: platform = platform_dl_loc['platform'] download_type = platform_dl_loc['download_type'] location = platform_dl_loc['location'] if platform not in self.platforms: raise SDKException( 'DownloadCenter', '116', 'Available platforms: {0}'.format(self.platforms) ) if download_type not in self.download_types: raise SDKException( 'DownloadCenter', '117', 'Available download types: {0}'.format(self.download_types) ) package_repository = kwargs.get('repository', self.servers_for_browse[0]) package_repository_id = self._servers_for_browse[package_repository]['id'] package_repository_name = self._servers_for_browse[package_repository]['internal_name'] temp = { "@name": platform, "@readMeLocation": readme_location, "@location": location, "@id": self._platforms[platform]['id'], "downloadType": { "@name": download_type, "@id": self._download_types[download_type]['id'] }, 'pkgRepository': { '@repositoryId': package_repository_id, '@respositoryName': package_repository_name }, '@size': 186646528 } platforms.append(temp) del platform del download_type del location del temp del platform_download_locations valid_from = kwargs.get('valid_from', time.strftime('%d/%m/%Y', time.localtime())) valid_from = int(time.mktime(time.strptime(valid_from, '%d/%m/%Y'))) valid_to = kwargs.get('valid_to', '') if valid_to: valid_to = int(time.mktime(time.strptime(valid_from, '%d/%m/%Y'))) sub_category = { "@entityType": 1, "@categoryId": self._categories[category]['id'] } if 'sub_category' in kwargs: sub_category_name = kwargs['sub_category'] sub_categories = self.sub_categories(category) if sub_category_name in sub_categories: sub_category["@id"] = self._categories[category][ 'sub_categories'][sub_category_name]['id'] else: raise SDKException( 'DownloadCenter', '109', 'Available Sub Categories: {0}'.format(sub_categories) ) del sub_categories vendor = kwargs.get('vendor', '') if vendor and vendor in self.vendors: vendor = self._vendors[vendor]['id'] visible_to = [] not_visible_to = [] early_preview_users = [] for user in kwargs.get('visible_to', []): if user in self.users_and_groups: temp = { '@name': user, '@guid': self._users_and_groups[user]['guid'], '@type': self._users_and_groups[user]['type'] } visible_to.append(temp) for user in kwargs.get('not_visible_to', []): if user in self.users_and_groups: temp = { '@name': user, '@guid': self._users_and_groups[user]['guid'], '@type': self._users_and_groups[user]['type'] } not_visible_to.append(temp) for user in kwargs.get('early_preview_users', []): if user in self.users_and_groups: temp = { '@name': user, '@guid': self._users_and_groups[user]['guid'], '@type': self._users_and_groups[user]['type'] } early_preview_users.append(temp) request_json = { "App_DCPackage": { "@name": package, "@description": kwargs.get('description', ''), "@validFrom": valid_from, "@validTo": valid_to, "@rank": kwargs.get('rank', 0), "category": { "@entityType": 0, "@id": self._categories[category]['id'] }, "subCategory": sub_category, "platforms": platforms, "productVersion": { "entityType": 3, "id": self._product_versions[version]['id'] }, "vendor": { "entityType": 6, "id": vendor }, "recutNumber": { "entityType": 4 }, "visibleTo": visible_to, "notVisibleTo": not_visible_to, "earlyPreviewUsers": early_preview_users, } } xml = xmltodict.unparse(request_json) xml = xml[xml.find('<App_'):] flag, response = self._cvpysdk_object.make_request( 'POST', self._services['UPLOAD_PACKAGE'], xml ) self.refresh() if flag: response = xmltodict.parse(response.text)['App_DCPackage'] error_code = response['errorDetail']['@errorCode'] if error_code != '0': error_message = response['errorDetail']['@errorMessage'] raise SDKException('DownloadCenter', '119', 'Error: {0}'.format(error_message)) else: response_string = self._update_response_(response.text) raise SDKException('Response', '101', response_string) def download_package(self, package, download_location, platform=None, download_type=None): """Downloads the given package from Download Center to the path specified. Args: package (str) -- name of the pacakge to be downloaded download_location (str) -- path on local machine to download the package at platform (str) -- platform to download the package for to be provided only if the package is added for multiple platforms default: None download_type (str) -- type of package to be downloaded to be provided only if multiple download types are present for single platform default: None Returns: str - path on local machine where the file has been downloaded Raises: SDKException: if package does not exist if platform not given: in case of multiple platforms if platform given does not exists in the list of supported platforms if download type is not specified: if case of multiple download types for the selected platform if download type given does not exists in the list of download types available if error returned by the server if response was not success """ # get the id of the package, if it is a valid package if not self.has_package(package): raise SDKException('DownloadCenter', '106') else: package = package.lower() package_id = self._packages[package]['id'] def get_platform_id(package, platform): """Checks if the platform is valid or not, and returns the platform id. If platform is set to None, gets the platform from the list of platforms, and the platform id. Args: package (str) -- name of the package to check the platform for platform (str) -- name of the platform to get the id of Returns: (str, str) - tuple consisting of the platform name as the first, and platform id as the second value Raises: SDKException: if platform is not given, and multiple platforms exists for the package if platform specified is not supported for the package """ platforms = self._packages[package]['platforms'] # check if the package has a single platform only, in case platform is not given if platform is None: # raise exception if multiple platforms exist for the package if len(platforms.keys()) > 1: raise SDKException('DownloadCenter', '110') # get the platform name and id, if it's a single platform else: platform = list(platforms.keys())[0] platform_id = platforms[platform]['id'] # raise exception if the platform does not exists in the list of supported platforms, # when it is given elif platform not in platforms: raise SDKException('DownloadCenter', '112') # get the id of the platform, # when it's given and exists in the list of supported platforms else: platform_id = platforms[platform]['id'] return platform, platform_id def get_download_type(package, platform, download_type): """Checks if the download type for the given package and platform is valid or not. If download type is set to None, gets the download type from the list of download types availalble for the given package and platform. Args: package (str) -- name of the package to get the download type for platform (str) -- name of the platform to get the download type of download_type (str) -- download type to be validated Returns: str - name of the download type Raises: SDKException: if download type is not given, and multiple download types exists if download type specified is not available for the package """ download_types = self._packages[package]['platforms'][platform]['download_type'] # check if the package has a single download type only, # in case download type is not given if download_type is None: # raise exception if multiple download types exist for the package and the platform if len(download_types) > 1: raise SDKException('DownloadCenter', '111') # get the download type name, if it's a single download type for the given platform else: download_type = download_types[0] # raise exception if the download type does not exists in the list, when it is given elif download_type not in download_types: raise SDKException('DownloadCenter', '113') # use the download type given by the user else: pass return download_type platform, platform_id = get_platform_id(package, platform) download_type = get_download_type(package, platform, download_type) if not os.path.exists(download_location): try: os.makedirs(download_location) except FileExistsError: pass request_id = '' file_name = None # ID: 3 is static for Download Center, and has the value "Package" # ID: 2, needs to provide the package id as the value for "name" # ID: 9, needs to provide the platform id as the value for "name" # ID: 11, needs to provide the download tyoe as the value for "name" # ID: 10 is static for Streamed downloads request_xml = ''' <DM2ContentIndexing_OpenFileReq requestId="{3}"> <fileParams id="3" name="Package"/> <fileParams id="2" name="{0}"/> <fileParams id="9" name="{1}"/> <fileParams id="11" name="{2}"/> <fileParams id="10" name="Streamed"/> </DM2ContentIndexing_OpenFileReq> ''' # execute the request to get the details like file name, and request id flag, response = self._cvpysdk_object.make_request( 'POST', self._services['DOWNLOAD_PACKAGE'], request_xml.format( package_id, platform_id, download_type, request_id ) ) if flag: error_list = response.json()['errList'] file_content = response.json()['fileContent'] if error_list: raise SDKException('DownloadCenter', '107', 'Error: {0}'.format(error_list)) file_name = file_content.get('fileName', file_name) request_id = file_content['requestId'] # full path of the file on local machine to be downloaded download_path = os.path.join(download_location, file_name) # execute request to get the stream of content # using request id returned in the previous response flag1, response1 = self._cvpysdk_object.make_request( 'POST', self._services['DOWNLOAD_VIA_STREAM'], request_xml.format(package_id, platform_id, download_type, request_id), stream=True ) # download chunks of 1MB each chunk_size = 1024 ** 2 if flag1: with open(download_path, "wb") as file_pointer: for content in response1.iter_content(chunk_size=chunk_size): file_pointer.write(content) else: response_string = self._update_response_(response1.text) raise SDKException('Response', '101', response_string) else: response_string = self._update_response_(response.text) raise SDKException('Response', '101', response_string) return download_path def delete_package(self, package): """Deletes the package from Download Center. Args: package (str) -- name of the package to be deleted Returns: None - if the package was deleted successfully Raises: SDKException: if no package exists with the given name if failed to delete the package if response is not success """ if not self.has_package(package): raise SDKException('DownloadCenter', '106') else: package = package.lower() package_id = self._packages[package]['id'] flag, response = self._cvpysdk_object.make_request( 'GET', self._services['DELETE_PACKAGE'] % package_id ) self.refresh() if flag: response = xmltodict.parse(response.text)['DM2ContentIndexing_CVDownloadCenterResp'] if 'errList' in response: error_code = response['errList']['@errorCode'] if error_code != '0': error_message = response['errList']['@errLogMessage'] raise SDKException('DownloadCenter', '119', 'Error: {0}'.format(error_message)) else: response_string = self._update_response_(response.text) raise SDKException('Response', '101', response_string) def refresh(self): """Refresh the properties of the DownloadCenter.""" self._get_properties() self._product_versions = {} self._servers_for_browse = {} self._users_and_groups = {} self._categories = {} self._download_types = {} self._vendors = {} self._platforms = {} self._packages = {} self._get_packages()
Instance variables
var categories
-
Returns the categories of products available at Download Center.
Expand source code Browse git
@property def categories(self): """Returns the categories of products available at Download Center.""" if not self._categories: categories = self._response['categories'] if isinstance(categories, dict): categories = [categories] for category in categories: category_id = category['@id'] temp = {} sub_categories = self._response['subCategories'] if isinstance(sub_categories, dict): sub_categories = [sub_categories] for sub_category in sub_categories: cat_id = sub_category['@categoryId'] if cat_id == category_id: temp[sub_category['@name']] = { 'id': sub_category['@id'], 'description': sub_category['@description'], 'entity_type': sub_category['@entityType'], 'attribute': sub_category['@attribute'] } self._categories[category['@name']] = { 'id': category_id, 'description': category['@description'], 'entity_type': category['@entityType'], 'attribute': category['@attribute'], 'sub_categories': temp } return list(self._categories)
var download_types
-
Returns the types of packages available for download at Download Center.
Expand source code Browse git
@property def download_types(self): """Returns the types of packages available for download at Download Center.""" if not self._download_types: download_types = self._response['downloadTypes'] if isinstance(download_types, dict): download_types = [download_types] for download_type in download_types: self._download_types[download_type['@name']] = { 'id': download_type['@id'], 'entity_type': download_type['@entityType'] } return list(self._download_types.keys())
var error_detail
-
Returns the error details.
Expand source code Browse git
@property def error_detail(self): """Returns the error details.""" return self._response['errorDetail']
var packages
-
Returns the packages available for download at Download Center.
Expand source code Browse git
@property def packages(self): """Returns the packages available for download at Download Center.""" if not self._packages: self._get_packages() return list(self._packages.keys())
var platforms
-
Returns the platforms supported for packages at Download Center.
Expand source code Browse git
@property def platforms(self): """Returns the platforms supported for packages at Download Center.""" if not self._platforms: platforms = self._response['platforms'] if isinstance(platforms, dict): platforms = [platforms] for platform in platforms: self._platforms[platform['@name']] = { 'id': platform['@id'], 'entity_type': platform['@entityType'], 'architecture': platform['@architectureName'] } return list(self._platforms.keys())
var product_versions
-
Return the versions of product available at Download Center.
Expand source code Browse git
@property def product_versions(self): """Return the versions of product available at Download Center.""" if not self._product_versions: product_versions = self._response['productVersions'] if isinstance(product_versions, dict): product_versions = [product_versions] for product_version in product_versions: self._product_versions[product_version['@name']] = { 'id': product_version['@id'], 'entity_type': product_version['@entityType'] } return list(self._product_versions.keys())
var servers_for_browse
-
Returns the servers available for browse at Download Center.
Expand source code Browse git
@property def servers_for_browse(self): """Returns the servers available for browse at Download Center.""" if not self._servers_for_browse: servers_for_browse = self._response['serversForBrowse'] if isinstance(servers_for_browse, dict): servers_for_browse = [servers_for_browse] for server_for_browse in servers_for_browse: self._servers_for_browse[server_for_browse['@name']] = { 'id': server_for_browse['@id'], 'internal_name': server_for_browse['@internalName'], 'entity_type': server_for_browse['@entityType'], 'attribute': server_for_browse['@attribute'] } return list(self._servers_for_browse.keys())
var users_and_groups
-
Returns the Users and User Groups available at Download Center.
Expand source code Browse git
@property def users_and_groups(self): """Returns the Users and User Groups available at Download Center.""" if not self._users_and_groups: users_and_groups = self._response['usersAndGroups'] if isinstance(users_and_groups, dict): users_and_groups = [users_and_groups] for user_and_group in self._response['usersAndGroups']: self._users_and_groups[user_and_group['@name']] = { 'id': user_and_group['@id'], 'provider_id': user_and_group['@providerId'], 'guid': user_and_group['@guid'], 'type': user_and_group['@type'], 'service_type': user_and_group['@serviceType'] } return list(self._users_and_groups.keys())
var vendors
-
Returns the vendors available at Download Center.
Expand source code Browse git
@property def vendors(self): """Returns the vendors available at Download Center.""" if not self._vendors: vendors = self._response['vendors'] if isinstance(vendors, dict): vendors = [vendors] for vendor in vendors: self._vendors[vendor['@name']] = { 'id': vendor['@id'], 'entity_type': vendor['@entityType'] } return list(self._vendors.keys())
Methods
def add_category(self, name, description=None)
-
Adds a new category with the given name, and description.
Args
name (str) – name of the category to add
description (str) – description for the category (optional) default: None
Returns
None - if the category was added successfully
Raises
SDKException: if category already exists
if failed to add the category
Expand source code Browse git
def add_category(self, name, description=None): """Adds a new category with the given name, and description. Args: name (str) -- name of the category to add description (str) -- description for the category (optional) default: None Returns: None - if the category was added successfully Raises: SDKException: if category already exists if failed to add the category """ if name in self.categories: raise SDKException('DownloadCenter', '104') self._process_category_request('add', name, description)
def add_sub_category(self, name, category, description=None)
-
Adds a new sub category with the given name, and description to the specified category.
Args
name (str) – name of the sub category to add
category (str) – name of the category to add the sub category to
description (str) – description for the sub category (optional) default: None
Returns
None - if the sub category was added successfully
Raises
SDKException: if category does not exist
if sub category already exists if failed to add the sub category
Expand source code Browse git
def add_sub_category(self, name, category, description=None): """Adds a new sub category with the given name, and description to the specified category. Args: name (str) -- name of the sub category to add category (str) -- name of the category to add the sub category to description (str) -- description for the sub category (optional) default: None Returns: None - if the sub category was added successfully Raises: SDKException: if category does not exist if sub category already exists if failed to add the sub category """ if name in self.sub_categories(category): raise SDKException('DownloadCenter', '105') self._process_sub_category_request('add', name, category, description)
def delete_category(self, name)
-
Deletes the category with the given name.
Args
name (str) – name of the category to delete
Returns
None - if the category was deleted successfully
Raises
SDKException: if category does not exists
if failed to delete the category
Expand source code Browse git
def delete_category(self, name): """Deletes the category with the given name. Args: name (str) -- name of the category to delete Returns: None - if the category was deleted successfully Raises: SDKException: if category does not exists if failed to delete the category """ if name not in self.categories: raise SDKException('DownloadCenter', '108') self._process_category_request('delete', name)
def delete_package(self, package)
-
Deletes the package from Download Center.
Args
package (str) – name of the package to be deleted
Returns
None - if the package was deleted successfully
Raises
SDKException: if no package exists with the given name
if failed to delete the package if response is not success
Expand source code Browse git
def delete_package(self, package): """Deletes the package from Download Center. Args: package (str) -- name of the package to be deleted Returns: None - if the package was deleted successfully Raises: SDKException: if no package exists with the given name if failed to delete the package if response is not success """ if not self.has_package(package): raise SDKException('DownloadCenter', '106') else: package = package.lower() package_id = self._packages[package]['id'] flag, response = self._cvpysdk_object.make_request( 'GET', self._services['DELETE_PACKAGE'] % package_id ) self.refresh() if flag: response = xmltodict.parse(response.text)['DM2ContentIndexing_CVDownloadCenterResp'] if 'errList' in response: error_code = response['errList']['@errorCode'] if error_code != '0': error_message = response['errList']['@errLogMessage'] raise SDKException('DownloadCenter', '119', 'Error: {0}'.format(error_message)) else: response_string = self._update_response_(response.text) raise SDKException('Response', '101', response_string)
def delete_sub_category(self, name, category)
-
Deletes the sub category from the category with the given name.
Args
name (str) – name of the sub category to delete
category (str) – name of the category to delete the sub category from
Returns
None - if the sub category was deleted successfully
Raises
SDKException: if sub category does not exist
if failed to delete the sub category
Expand source code Browse git
def delete_sub_category(self, name, category): """Deletes the sub category from the category with the given name. Args: name (str) -- name of the sub category to delete category (str) -- name of the category to delete the sub category from Returns: None - if the sub category was deleted successfully Raises: SDKException: if sub category does not exist if failed to delete the sub category """ if name not in self.sub_categories(category): raise SDKException('DownloadCenter', '109') self._process_sub_category_request('delete', name, category)
def download_package(self, package, download_location, platform=None, download_type=None)
-
Downloads the given package from Download Center to the path specified.
Args
package (str) – name of the pacakge to be downloaded
download_location (str) – path on local machine to download the package at
platform (str) – platform to download the package for
to be provided only if the package is added for multiple platforms default: None
download_type (str) – type of package to be downloaded
to be provided only if multiple download types are present for single platform default: None
Returns
str - path on local machine where the file has been downloaded
Raises
SDKException: if package does not exist
if platform not given: in case of multiple platforms if platform given does not exists in the list of supported platforms if download type is not specified: if case of multiple download types for the selected platform if download type given does not exists in the list of download types available if error returned by the server if response was not success
Expand source code Browse git
def download_package(self, package, download_location, platform=None, download_type=None): """Downloads the given package from Download Center to the path specified. Args: package (str) -- name of the pacakge to be downloaded download_location (str) -- path on local machine to download the package at platform (str) -- platform to download the package for to be provided only if the package is added for multiple platforms default: None download_type (str) -- type of package to be downloaded to be provided only if multiple download types are present for single platform default: None Returns: str - path on local machine where the file has been downloaded Raises: SDKException: if package does not exist if platform not given: in case of multiple platforms if platform given does not exists in the list of supported platforms if download type is not specified: if case of multiple download types for the selected platform if download type given does not exists in the list of download types available if error returned by the server if response was not success """ # get the id of the package, if it is a valid package if not self.has_package(package): raise SDKException('DownloadCenter', '106') else: package = package.lower() package_id = self._packages[package]['id'] def get_platform_id(package, platform): """Checks if the platform is valid or not, and returns the platform id. If platform is set to None, gets the platform from the list of platforms, and the platform id. Args: package (str) -- name of the package to check the platform for platform (str) -- name of the platform to get the id of Returns: (str, str) - tuple consisting of the platform name as the first, and platform id as the second value Raises: SDKException: if platform is not given, and multiple platforms exists for the package if platform specified is not supported for the package """ platforms = self._packages[package]['platforms'] # check if the package has a single platform only, in case platform is not given if platform is None: # raise exception if multiple platforms exist for the package if len(platforms.keys()) > 1: raise SDKException('DownloadCenter', '110') # get the platform name and id, if it's a single platform else: platform = list(platforms.keys())[0] platform_id = platforms[platform]['id'] # raise exception if the platform does not exists in the list of supported platforms, # when it is given elif platform not in platforms: raise SDKException('DownloadCenter', '112') # get the id of the platform, # when it's given and exists in the list of supported platforms else: platform_id = platforms[platform]['id'] return platform, platform_id def get_download_type(package, platform, download_type): """Checks if the download type for the given package and platform is valid or not. If download type is set to None, gets the download type from the list of download types availalble for the given package and platform. Args: package (str) -- name of the package to get the download type for platform (str) -- name of the platform to get the download type of download_type (str) -- download type to be validated Returns: str - name of the download type Raises: SDKException: if download type is not given, and multiple download types exists if download type specified is not available for the package """ download_types = self._packages[package]['platforms'][platform]['download_type'] # check if the package has a single download type only, # in case download type is not given if download_type is None: # raise exception if multiple download types exist for the package and the platform if len(download_types) > 1: raise SDKException('DownloadCenter', '111') # get the download type name, if it's a single download type for the given platform else: download_type = download_types[0] # raise exception if the download type does not exists in the list, when it is given elif download_type not in download_types: raise SDKException('DownloadCenter', '113') # use the download type given by the user else: pass return download_type platform, platform_id = get_platform_id(package, platform) download_type = get_download_type(package, platform, download_type) if not os.path.exists(download_location): try: os.makedirs(download_location) except FileExistsError: pass request_id = '' file_name = None # ID: 3 is static for Download Center, and has the value "Package" # ID: 2, needs to provide the package id as the value for "name" # ID: 9, needs to provide the platform id as the value for "name" # ID: 11, needs to provide the download tyoe as the value for "name" # ID: 10 is static for Streamed downloads request_xml = ''' <DM2ContentIndexing_OpenFileReq requestId="{3}"> <fileParams id="3" name="Package"/> <fileParams id="2" name="{0}"/> <fileParams id="9" name="{1}"/> <fileParams id="11" name="{2}"/> <fileParams id="10" name="Streamed"/> </DM2ContentIndexing_OpenFileReq> ''' # execute the request to get the details like file name, and request id flag, response = self._cvpysdk_object.make_request( 'POST', self._services['DOWNLOAD_PACKAGE'], request_xml.format( package_id, platform_id, download_type, request_id ) ) if flag: error_list = response.json()['errList'] file_content = response.json()['fileContent'] if error_list: raise SDKException('DownloadCenter', '107', 'Error: {0}'.format(error_list)) file_name = file_content.get('fileName', file_name) request_id = file_content['requestId'] # full path of the file on local machine to be downloaded download_path = os.path.join(download_location, file_name) # execute request to get the stream of content # using request id returned in the previous response flag1, response1 = self._cvpysdk_object.make_request( 'POST', self._services['DOWNLOAD_VIA_STREAM'], request_xml.format(package_id, platform_id, download_type, request_id), stream=True ) # download chunks of 1MB each chunk_size = 1024 ** 2 if flag1: with open(download_path, "wb") as file_pointer: for content in response1.iter_content(chunk_size=chunk_size): file_pointer.write(content) else: response_string = self._update_response_(response1.text) raise SDKException('Response', '101', response_string) else: response_string = self._update_response_(response.text) raise SDKException('Response', '101', response_string) return download_path
def get_package_details(self, package)
-
Returns the details of the package, like the package description, platforms, etc.
Args
package (str) – name of the package to get the details of
Returns
dict - dictionary consisting of the details of the package
Raises
SDKException: if package does not exist
Expand source code Browse git
def get_package_details(self, package): """Returns the details of the package, like the package description, platforms, etc. Args: package (str) -- name of the package to get the details of Returns: dict - dictionary consisting of the details of the package Raises: SDKException: if package does not exist """ if not self.has_package(package): raise SDKException('DownloadCenter', '106') package = package.lower() package_detail = self._packages[package] output = { 'name': package, 'description': package_detail['description'], 'platforms': {} } platforms = package_detail['platforms'] for platform in platforms: output['platforms'][platform] = platforms[platform]['download_type'] return output
def has_package(self, package)
-
Checks if a package with the given name already exists at Download Center or not.
Args
package (str) – name of the package to check
Returns
bool - boolean specifying whether the package exists or not
Expand source code Browse git
def has_package(self, package): """Checks if a package with the given name already exists at Download Center or not. Args: package (str) -- name of the package to check Returns: bool - boolean specifying whether the package exists or not """ return self.packages and package.lower() in self.packages
def refresh(self)
-
Refresh the properties of the DownloadCenter.
Expand source code Browse git
def refresh(self): """Refresh the properties of the DownloadCenter.""" self._get_properties() self._product_versions = {} self._servers_for_browse = {} self._users_and_groups = {} self._categories = {} self._download_types = {} self._vendors = {} self._platforms = {} self._packages = {} self._get_packages()
def sub_categories(self, category)
-
Returns the sub categories available for the specified category.
Args
category (str) – name of the category to get the sub categories of
Returns
list - list of sub categories available for the given category
Raises
SDKException: if category does not exist
Expand source code Browse git
def sub_categories(self, category): """Returns the sub categories available for the specified category. Args: category (str) -- name of the category to get the sub categories of Returns: list - list of sub categories available for the given category Raises: SDKException: if category does not exist """ if category not in self.categories: raise SDKException('DownloadCenter', '103') return list(self._categories[category]['sub_categories'].keys())
def update_category(self, name, new_name, description=None)
-
Updates the name and description of the category with the given name.
Args
name (str) – name of the existing category to update
new_name (str) – new name for the category
description (str) – description for the category (optional)
default: None
Returns
None - if the category information was updated successfully
Raises
SDKException: if no category exists with the given name
if category already exists with the new name specified if failed to update the category
Expand source code Browse git
def update_category(self, name, new_name, description=None): """Updates the name and description of the category with the given name. Args: name (str) -- name of the existing category to update new_name (str) -- new name for the category description (str) -- description for the category (optional) default: None Returns: None - if the category information was updated successfully Raises: SDKException: if no category exists with the given name if category already exists with the new name specified if failed to update the category """ if name not in self.categories: raise SDKException('DownloadCenter', '108') if new_name in self.categories: raise SDKException('DownloadCenter', '104') self._process_category_request('update', name, description, new_name)
def update_sub_category(self, name, category, new_name, description=None)
-
Updates the name and description of the sub category with the given name and category.
Args
name (str) – name of the sub category to update the details of
category (str) – name of the category to update the sub category of
new_name (str) – new name for the sub category
description (str) – description for the sub category (optional)
default: None
Returns
None - if the sub category information was updated successfully
Raises
SDKException: if no sub category exists with the given name
if sub category already exists with the new name specified if failed to update the sub category
Expand source code Browse git
def update_sub_category(self, name, category, new_name, description=None): """Updates the name and description of the sub category with the given name and category. Args: name (str) -- name of the sub category to update the details of category (str) -- name of the category to update the sub category of new_name (str) -- new name for the sub category description (str) -- description for the sub category (optional) default: None Returns: None - if the sub category information was updated successfully Raises: SDKException: if no sub category exists with the given name if sub category already exists with the new name specified if failed to update the sub category """ if name not in self.sub_categories(category): raise SDKException('DownloadCenter', '109') if new_name in self.sub_categories(category): raise SDKException('DownloadCenter', '105') self._process_sub_category_request('update', name, category, description, new_name)
def upload_package(self, package, category, version, platform_download_locations, **kwargs)
-
Uploads the given package to Download Center.
Args
package (str) – name of the package to upload
category (str) – category to upload the package for
version (str) – product version for package to upload
platform_download_locations (list) – list consisting of dictionaries
where each dictionary contains the values for the platform, download type, and location of the file e.g.: [ { 'platform': 'Windows-x64', 'download_type': 'Exe', 'location': 'C:\location1' }, { 'platform': 'Windows-x64', 'download_type': 'Script', 'location': 'C:\location2' }, { 'platform': 'Windows-x86', 'download_type': 'Exe', 'location': 'C:\location3' }, { 'platform': 'Windows-x86', 'download_type': 'Script', 'location': 'C:\location4' } ]
**kwargs:
valid_from (str) -- date from which the package should be valid if the value is not specified, then current date is taken as it's value format: DD/MM/YYYY description (str) -- description of the package readme_location (str) -- location of the readme file readme file should have one of the following extensions [**.txt**, **.pdf**, **.doc**, **.docx**] sub_category (str) -- sub category to associate the package with vendor (str) -- vendor / distributor of the package valid_to (str) -- date till which the package should be valid format: DD/MM/YYYY repository (str) -- name of the repository to add the package to if this value is not defined, the first repository will be taken by default visible_to (list) -- list of users, the package should be visible to not_visible_to (list) -- users, the package should not be visible to early_preview_users (list) -- list of users, the package should be visible to before release
Returns
None - if the package was uploaded successfully to Download Center
Raises
SDKException: if package with given name already exists
if category does not exists at Download Center if version is not supported at Download Center if platform is not supported at Download Center if download type is not supported at Download Center if sub category not present for the given category if failed to upload the package if error returned by the server if response was not success
Expand source code Browse git
def upload_package(self, package, category, version, platform_download_locations, **kwargs): """Uploads the given package to Download Center. Args: package (str) -- name of the package to upload category (str) -- category to upload the package for version (str) -- product version for package to upload platform_download_locations (list) -- list consisting of dictionaries where each dictionary contains the values for the platform, download type, and location of the file e.g.: [ { 'platform': 'Windows-x64', 'download_type': 'Exe', 'location': 'C:\\location1' }, { 'platform': 'Windows-x64', 'download_type': 'Script', 'location': 'C:\\location2' }, { 'platform': 'Windows-x86', 'download_type': 'Exe', 'location': 'C:\\location3' }, { 'platform': 'Windows-x86', 'download_type': 'Script', 'location': 'C:\\location4' } ] **kwargs: valid_from (str) -- date from which the package should be valid if the value is not specified, then current date is taken as it's value format: DD/MM/YYYY description (str) -- description of the package readme_location (str) -- location of the readme file readme file should have one of the following extensions [**.txt**, **.pdf**, **.doc**, **.docx**] sub_category (str) -- sub category to associate the package with vendor (str) -- vendor / distributor of the package valid_to (str) -- date till which the package should be valid format: DD/MM/YYYY repository (str) -- name of the repository to add the package to if this value is not defined, the first repository will be taken by default visible_to (list) -- list of users, the package should be visible to not_visible_to (list) -- users, the package should not be visible to early_preview_users (list) -- list of users, the package should be visible to before release Returns: None - if the package was uploaded successfully to Download Center Raises: SDKException: if package with given name already exists if category does not exists at Download Center if version is not supported at Download Center if platform is not supported at Download Center if download type is not supported at Download Center if sub category not present for the given category if failed to upload the package if error returned by the server if response was not success """ if self.has_package(package): raise SDKException('DownloadCenter', '114') if category not in self.categories: raise SDKException( 'DownloadCenter', '103', 'Available categories: {0}'.format(self.categories) ) if version not in self.product_versions: raise SDKException( 'DownloadCenter', '115', 'Available versions: {0}'.format(self.product_versions) ) platforms = [] readme_location = kwargs.get('readme_location', '') readme_file_extensions = ['.txt', '.pdf', '.doc', '.docx'] if readme_location: if os.path.splitext(readme_location)[1] not in readme_file_extensions: raise SDKException('DownloadCenter', '118') del readme_file_extensions for platform_dl_loc in platform_download_locations: platform = platform_dl_loc['platform'] download_type = platform_dl_loc['download_type'] location = platform_dl_loc['location'] if platform not in self.platforms: raise SDKException( 'DownloadCenter', '116', 'Available platforms: {0}'.format(self.platforms) ) if download_type not in self.download_types: raise SDKException( 'DownloadCenter', '117', 'Available download types: {0}'.format(self.download_types) ) package_repository = kwargs.get('repository', self.servers_for_browse[0]) package_repository_id = self._servers_for_browse[package_repository]['id'] package_repository_name = self._servers_for_browse[package_repository]['internal_name'] temp = { "@name": platform, "@readMeLocation": readme_location, "@location": location, "@id": self._platforms[platform]['id'], "downloadType": { "@name": download_type, "@id": self._download_types[download_type]['id'] }, 'pkgRepository': { '@repositoryId': package_repository_id, '@respositoryName': package_repository_name }, '@size': 186646528 } platforms.append(temp) del platform del download_type del location del temp del platform_download_locations valid_from = kwargs.get('valid_from', time.strftime('%d/%m/%Y', time.localtime())) valid_from = int(time.mktime(time.strptime(valid_from, '%d/%m/%Y'))) valid_to = kwargs.get('valid_to', '') if valid_to: valid_to = int(time.mktime(time.strptime(valid_from, '%d/%m/%Y'))) sub_category = { "@entityType": 1, "@categoryId": self._categories[category]['id'] } if 'sub_category' in kwargs: sub_category_name = kwargs['sub_category'] sub_categories = self.sub_categories(category) if sub_category_name in sub_categories: sub_category["@id"] = self._categories[category][ 'sub_categories'][sub_category_name]['id'] else: raise SDKException( 'DownloadCenter', '109', 'Available Sub Categories: {0}'.format(sub_categories) ) del sub_categories vendor = kwargs.get('vendor', '') if vendor and vendor in self.vendors: vendor = self._vendors[vendor]['id'] visible_to = [] not_visible_to = [] early_preview_users = [] for user in kwargs.get('visible_to', []): if user in self.users_and_groups: temp = { '@name': user, '@guid': self._users_and_groups[user]['guid'], '@type': self._users_and_groups[user]['type'] } visible_to.append(temp) for user in kwargs.get('not_visible_to', []): if user in self.users_and_groups: temp = { '@name': user, '@guid': self._users_and_groups[user]['guid'], '@type': self._users_and_groups[user]['type'] } not_visible_to.append(temp) for user in kwargs.get('early_preview_users', []): if user in self.users_and_groups: temp = { '@name': user, '@guid': self._users_and_groups[user]['guid'], '@type': self._users_and_groups[user]['type'] } early_preview_users.append(temp) request_json = { "App_DCPackage": { "@name": package, "@description": kwargs.get('description', ''), "@validFrom": valid_from, "@validTo": valid_to, "@rank": kwargs.get('rank', 0), "category": { "@entityType": 0, "@id": self._categories[category]['id'] }, "subCategory": sub_category, "platforms": platforms, "productVersion": { "entityType": 3, "id": self._product_versions[version]['id'] }, "vendor": { "entityType": 6, "id": vendor }, "recutNumber": { "entityType": 4 }, "visibleTo": visible_to, "notVisibleTo": not_visible_to, "earlyPreviewUsers": early_preview_users, } } xml = xmltodict.unparse(request_json) xml = xml[xml.find('<App_'):] flag, response = self._cvpysdk_object.make_request( 'POST', self._services['UPLOAD_PACKAGE'], xml ) self.refresh() if flag: response = xmltodict.parse(response.text)['App_DCPackage'] error_code = response['errorDetail']['@errorCode'] if error_code != '0': error_message = response['errorDetail']['@errorMessage'] raise SDKException('DownloadCenter', '119', 'Error: {0}'.format(error_message)) else: response_string = self._update_response_(response.text) raise SDKException('Response', '101', response_string)