def alter_cube_cache_status(connection: "Connection", id: str, active: bool = None, loaded: bool = None, throw_error: bool = True): """Alter an cube cache status. In one request it is possible to set either 'active' or 'loaded', never both. Args: connection: MicroStrategy connection object returned by `connection.Connection()`. id (string): cube cache id, active (bool, optional): make cube cache active (True) or inactive (False) loaded (bool, optional): load (True) or unload (False) the cube cache throw_error (bool, optional): Flag indicates if the error should be thrown. Returns: Complete HTTP response object. """ if loaded is not None: loaded = 'loaded' if loaded else 'unloaded' body = {'state': {'active': active, 'loadedState': loaded}} body = delete_none_values(body) return connection.patch( url=f'{connection.base_url}/api/monitors/caches/cubes/{id}', headers={'Prefer': 'respond-async'}, json=body)
def create(cls, connection: "Connection", name: str, username: str, password: str, description: str = None) -> "DatasourceLogin": """Create a new datasource login. Args: connection: MicroStrategy connection object returned by `connection.Connection()` name: login object name username: username description: login object description password: database password to be used by the database login Returns: DatasourceConnection object. """ body = { "name": name, "description": description, "username": username, "password": password } body = helper.delete_none_values(body) response = datasources.create_datasource_login(connection, body).json() if config.verbose: logger.info( f"Successfully created datasource login named: '{response.get('name')}' " f"with ID: '{response.get('id')}'" ) return cls.from_dict(source=response, connection=connection)
def to_dict(self, camel_case=True): result = delete_none_values({ "type": self.type, "function": self.function.value, "children": [child.to_dict(camel_case) for child in self.children] }) return snake_to_camel(result) if camel_case else result
def to_dict(self, camel_case=True): result = delete_none_values({ "type": self.type, "predicate_id": self.predicate_id, "predicate_tree": self._predicate_tree_to_dict(camel_case) }) return snake_to_camel(result) if camel_case else result
def __prepare_body(qualification: dict, id: str = None, name: str = None, folder_id: str = None, description: str = None, top_level: List[dict] = [], bottom_level: List[dict] = []) -> dict: information = ObjectInformation(object_id=id, sub_type="md_security_filter", name=name, description=description, destination_folder_id=folder_id) return helper.delete_none_values({ "information": information.to_dict(), "qualification": qualification, "topLevel": top_level, "bottomLevel": bottom_level })
def create(cls, connection: "Connection", name: str, device_type: Union[DeviceType, str], transmitter: Union[Transmitter, str], device_properties: Union[dict, Dictable], description: str = None) -> "Device": """Create a new device. Args: connection: MicroStrategy connection object returned by `connection.Connection()` name: device object name device_type: type of the device transmitter: Transmitter object description: device object description device_properties: properties of the device Returns: Device object. """ device_type = get_enum_val(device_type, DeviceType) device_properties = device_properties.to_dict() if isinstance( device_properties, Dictable) else device_properties transmitter_id = get_objects_id(transmitter, Transmitter) body = { "name": name, "description": description, "deviceType": device_type, "transmitter": { "id": transmitter_id, }, "deviceProperties": { device_type: device_properties } } body = delete_none_values(body) response = devices.create_device(connection, body).json() if config.verbose: logger.info( f"Successfully created device named: '{name}' with ID: '{response['id']}'." ) return cls.from_dict(source=response, connection=connection)
def unpack_information_inner(*args, **kwargs): if kwargs.get('body'): info = { "information": { "objectId": kwargs['body'].pop('id', None), "subType": kwargs['body'].pop('subType', None), "name": kwargs['body'].pop('name', None), "isEmbedded": kwargs['body'].pop('isEmbedded', None), "description": kwargs['body'].pop('description', None), "dateCreated": kwargs['body'].pop('dateCreated', None), "dateModified": kwargs['body'].pop('dateModified', None), "destinationFolderId": kwargs['body'].pop('destinationFolderId', None), "versionId": kwargs['body'].pop('versionId', None), "path": kwargs['body'].pop('path', None), "primaryLocale": kwargs['body'].pop('primaryLocale', None), } } info = delete_none_values(info) if info['information']: kwargs['body'].update(info) resp = func(*args, **kwargs) response_json = resp.json() if response_json.get('information'): response_json.update(response_json.pop('information')) response_json['id'] = response_json.pop('objectId', None) resp.encoding, resp._content = 'utf-8', dumps( response_json).encode('utf-8') return resp
def update_config(self, package_config: PackageConfig): body = package_config.to_dict() body = helper.delete_none_values(body) body = helper.snake_to_camel(body) migration.update_package_holder(self.connection, body, self.id).json() total_time = 0 # Wait until update ready while True: response = migration.get_package_holder(self.connection, self.id, show_content=False).json() if response.get('status') == 'ready': break sleep(TIMEOUT_INCREMENT) total_time += TIMEOUT_INCREMENT if total_time > TIMEOUT: logger.warning('Time out on updating package') return False self.fetch() return True
def create(cls, connection: 'Connection', name: str, linked_user: Union['User', str], contact_addresses: Iterable[Union['ContactAddress', dict]], description: Optional[str] = None, enabled: bool = True) -> 'Contact': """Create a new contact. Args: connection: MicroStrategy connection object returned by `connection.Connection()` name: contact name linked_user: user linked to contact contact_addresses: list of contact addresses description: description of contact enabled: specifies if contact should be enabled Returns: Contact object """ body = { 'name': name, 'description': description, 'enabled': enabled, 'linkedUser': { 'id': get_objects_id(linked_user, User) }, 'contactAddresses': [ address.to_dict() if isinstance(address, ContactAddress) else address for address in contact_addresses ], } body = delete_none_values(body) response = contacts.create_contact(connection, body).json() if config.verbose: logger.info( f"Successfully created contact named: '{name}' with ID: '{response['id']}'" ) return cls.from_dict(source=response, connection=connection)
def create( cls, connection: "Connection", name: str, description: Optional[str] = None, acg: Optional[int] = None, execution_mode: Union[str, ExecutionMode] = None, max_cancel_attempt_time: Optional[int] = None, max_query_exe_time: Optional[int] = None, max_connection_attempt_time: Optional[int] = None, connection_lifetime: Optional[int] = None, connection_idle_timeout: Optional[int] = None, char_encoding_windows: Union[str, CharEncoding] = None, char_encoding_unix: Union[str, CharEncoding] = None, table_prefix: Optional[str] = None, connection_string: Optional[str] = None, parameterized_queries: Optional[bool] = None, extended_fetch: Optional[bool] = None, datasource_login: Union[DatasourceLogin, str, None] = None, database_type: Optional[str] = None, database_version: Optional[str] = None, driver_type: Union[str, DriverType] = None, oauth_parameter: Optional[str] = None) -> "DatasourceConnection": """Create a new datasource connection on the I-Server. Args: connection: MicroStrategy connection object returned by `connection.Connection()`. name: Unique datasource connection name. description: Datasource connection description. acg: Object access rights. It's a bit vector where bits are defined at [EnumDSSXMLAccessRightFlags]. execution_mode: ExecutionMode Enum specifying how SQL statements will be executed on a physical database connection made. max_cancel_attempt_time: Number of seconds before being timed out when attempting to make a connection. max_query_exe_time: Number of seconds during which a query must be executed before being timed out. max_connection_attempt_time: Number of seconds connection attempts to be made before timing out. connection_lifetime: Number of seconds of the connection lifetime. connection_idle_timeout: Number of seconds before being timed out when the connection is idle. char_encoding_windows: CharEncoding Enum specifying the encoding across connection for Windows drivers. char_encoding_unix: CharEncoding Enum specifying the encoding across connection for Unix drivers. table_prefix: String prefixed to the names of all temporary tables created by the Query Engine for this connection during report execution with this string. connection_string: Database connection string. parameterized_queries: Specifies whether parameterized queries are enabled. extended_fetch: Specifies whether or not to use the extended fetch ODBC call to retrieve data from the database connection. driver_type: DriverType Enum specifying Driver used for database connection. oauth_parameter: Used for authentication with oAuth. datasource_login: `DatasourceLogin` object or ID database_type: Database type database_version: Database version Returns: DatasourceConnection object. """ login_id = get_objects_id(datasource_login, DatasourceLogin) body = { "name": name, "description": description, "acg": acg, "executionMode": get_enum_val(execution_mode, ExecutionMode), "maxCancelAttemptTime": max_cancel_attempt_time, "maxQueryExeTime": max_query_exe_time, "maxConnectionAttemptTime": max_connection_attempt_time, "connectionLifetime": connection_lifetime, "connectionIdleTimeout": connection_idle_timeout, "charEncodingWindows": get_enum_val(char_encoding_windows, CharEncoding), "charEncodingUnix": get_enum_val(char_encoding_unix, CharEncoding), "tablePrefix": table_prefix, "connectionString": connection_string, "parameterizedQueries": parameterized_queries, "extendedFetch": extended_fetch, "database": { "login": { "id": login_id }, "type": database_type, "version": database_version }, "driverType": get_enum_val(driver_type, DriverType), "oauthParameter": oauth_parameter } body = helper.delete_none_values(body) response = datasources.create_datasource_connection(connection, body).json() if config.verbose: logger.info( f"Successfully created datasource connection named: '{response.get('name')}' " f"with ID: '{response.get('id')}'") return cls.from_dict(source=response, connection=connection)
def alter( self, name: str = None, allow_delivery_changes: bool = None, allow_personalization_changes: bool = None, allow_unsubscribe: bool = None, send_now: bool = False, owner_id: str = None, schedules_ids: Union[str, List[str]] = None, contents: Content = None, recipients: Union[List[str], List[dict]] = None, delivery: Union[Delivery, dict] = None, delivery_mode: str = None, custom_msg=None, delivery_expiration_date: str = None, contact_security: bool = None, filename: str = None, compress: bool = None, space_delimiter: str = None, email_subject: str = None, email_message: str = None, email_send_content_as: str = None, overwrite_older_version: bool = None, zip_filename: str = None, zip_password_protect: bool = None, zip_password: str = None, file_burst_sub_folder: str = None, printer_copies: int = None, printer_range_start: int = None, printer_range_end: int = None, printer_collated: bool = None, printer_orientation: str = None, printer_use_print_range: bool = None, cache_type: str = None, shortcut_cache_format: str = None, mobile_client_type: str = None, device_id: str = None, do_not_create_update_caches: bool = None, re_run_hl: bool = None, ): """Alter subscription. Args: connection(Connection): a MicroStrategy connection object name(str): name of the subscription, application_id(str): application ID, allow_delivery_changes(bool): whether the recipients can change the delivery of the subscription, allow_personalization_changes(bool): whether the recipients can personalize the subscription, allow_unsubscribe(bool): whether the recipients can unsubscribe from the subscription, send_now(bool): indicates whether to execute the subscription immediately, owner_id(str): ID of the subscription owner, by default logged in user ID, schedules_ids (Union[str, List[str]]) = Schedules IDs, contents (Content): The content of the subscription. recipients (Union[List[str], List[dict]]): list of recipients IDs or dicts, delivery_mode(str, enum): the subscription delivery mode [EMAIL, FILE, PRINTER, HISTORY_LIST, CACHE, MOBILE, FTP, SNAPSHOT, PERSONAL_VIEW, SHARED_LINK, UNSUPPORTED], delivery_expiration_date(str): expiration date of the subscription, format should be yyyy-MM-dd, contact_security(bool): whether to use contact security for each contact group member, filename(str): the filename that will be delivered when the subscription is executed, compress(bool): whether to compress the file space_delimiter(str): space delimiter, email_subject(str): email subject associated with the subscription, email_message(str): email body of subscription, email_send_content_as(str,enum): [data, data_and_history_list, data_and_link_and_history_list, link_and_history_list], overwrite_older_version(bool): whether the current subscription will overwrite earlier versions of the same report or document in the history list, zip_filename(str): filename of the compressed content, zip_password_protect(bool): whether to password protect zip file, zip_password(str): optional password for the compressed file file_burst_sub_folder(str): burst sub folder, printer_copies(int): the number of copies that should be printed, printer_range_start(int): the number indicating the first report page that should be printed, printer_range_end(int): the number indicating the last report page that should be printed, printer_collated(bool): whether the printing should be collated, printer_orientation(str,enum): [ PORTRAIT, LANDSCAPE ] printer_use_print_range(bool): whether print range should be used, cache_type(str,enum): [RESERVED, SHORTCUT, BOOKMARK, SHORTCUTWITHBOOKMARK] shortcut_cache_format(str,enum): [RESERVED, JSON, BINARY, BOTH] mobile_client_type(str,enum): [RESERVED, BLACKBERRY, PHONE, TABLET, ANDROID] device_id(str): the mobile target application, do_not_create_update_caches(bool): whether the current subscription will overwrite earlier versions of the same report or document in the history list, re_run_hl(bool): whether subscription will re-run against warehouse """ def validate(body): for key, value in body.items(): if key == 'send_now': pass elif type(value) is not self._AVAILABLE_ATTRIBUTES.get(key): helper.exception_handler( "{} is not a valid type of {}, valid type is {}". format(type(value), key, self._AVAILABLE_ATTRIBUTES.get(key)), TypeError) def is_changed(nested=None, **kwargs): for key, value in kwargs.items(): if nested: return value if value != nested and value is not None else nested else: current_val = self.__dict__.get(key) # if not current_val: we need to get return value if value != current_val and value is not None else current_val # Schedules logic schedules_ids = schedules_ids if isinstance(schedules_ids, list) else [schedules_ids] schedules_ids = [s for s in schedules_ids if s is not None] schedules = [{ 'id': sch_id } for sch_id in schedules_ids] if schedules_ids else [{ 'id': trig['id'] } for trig in self.schedules] # Content logic if contents: contents = contents if isinstance(contents, list) else [contents] content_type_msg = "Contents must be dictionaries or Content objects." contents = [ content.to_dict( camel_case=True) if isinstance(content, Content) else content if isinstance(content, dict) else helper.exception_handler(content_type_msg, TypeError) for content in contents ] else: contents = self.contents # Delivery logic if delivery: temp_delivery = Delivery.from_dict(delivery) if isinstance( delivery, dict) else delivery else: temp_delivery = self.__change_delivery_properties( delivery_mode, delivery_expiration_date, contact_security, email_subject, email_message, filename, compress, None, zip_password, zip_password_protect, space_delimiter, email_send_content_as, overwrite_older_version, file_burst_sub_folder, printer_copies, printer_range_start, printer_range_end, printer_collated, printer_orientation, printer_use_print_range, cache_type, shortcut_cache_format, mobile_client_type, device_id, do_not_create_update_caches, re_run_hl) delivery = temp_delivery.to_dict(camel_case=True) # Recipients logic recipients = is_changed(recipients=recipients) recipients = Subscription._validate_recipients(self.connection, contents, recipients, self.application_id, delivery['mode']) body = { "name": is_changed(name=name), "allowDeliveryChanges": is_changed(allow_delivery_changes=allow_delivery_changes), "allowPersonalizationChanges": is_changed( allow_personalization_changes=allow_personalization_changes), "allowUnsubscribe": is_changed(allow_unsubscribe=allow_unsubscribe), "sendNow": send_now, 'owner': { 'id': is_changed(nested=self.owner['id'], owner_id=owner_id) }, "schedules": schedules, "contents": contents, "recipients": recipients, "delivery": delivery, } validate(helper.camel_to_snake(body)) body = helper.delete_none_values(body) response = subscriptions.update_subscription(self.connection, self.id, self.application_id, body) if response.ok: response = response.json() response = helper.camel_to_snake(response) for key, value in response.items(): self.__setattr__(key, value) if config.verbose: print(custom_msg if custom_msg else "Updated subscription '{}' with ID: {}.". format(self.name, self.id))
def __create( cls, connection: Connection, name: str, application_id: str = None, application_name: str = None, allow_delivery_changes: bool = None, allow_personalization_changes: bool = None, allow_unsubscribe: bool = None, send_now: bool = None, owner_id: str = None, schedules_ids: Union[str, List[str]] = None, contents: Content = None, recipients: Union[List[dict], List[str]] = None, delivery: Union[Delivery, dict] = None, delivery_mode: str = 'EMAIL', delivery_expiration_date: str = None, contact_security: bool = True, filename: str = None, compress: bool = False, space_delimiter: str = None, email_subject: str = None, email_message: str = None, email_send_content_as: str = 'data', overwrite_older_version: bool = False, zip_filename: str = None, zip_password_protect: bool = None, zip_password: str = None, file_burst_sub_folder: str = None, printer_copies: int = 1, printer_range_start: int = 0, printer_range_end: int = 0, printer_collated: bool = True, printer_orientation: str = "PORTRAIT", printer_use_print_range: bool = False, cache_type: str = "RESERVED", shortcut_cache_format: str = "RESERVED", mobile_client_type: str = "RESERVED", device_id: str = None, do_not_create_update_caches: bool = True, re_run_hl: bool = True, ): """Creates a subscription Create_Subscription_Outline. Args: connection(Connection): a MicroStrategy connection object name(str): name of the subscription, application_id(str): application ID, application_name(str): application name, allow_delivery_changes(bool): whether the recipients can change the delivery of the subscription, allow_personalization_changes(bool): whether the recipients can personalize the subscription, allow_unsubscribe(bool): whether the recipients can unsubscribe from the subscription, send_now(bool): indicates whether to execute the subscription immediately, owner_id(str): ID of the subscription owner, by default logged in user ID, schedules_ids (Union[str, List[str]]) = Schedules IDs, contents (Content): The content settings. recipients (List[dict],List[str]): list of recipients IDs or dicts, delivery(Union[Delivery,dict]): delivery object or dict delivery_mode(str, enum): the subscription delivery mode [EMAIL, FILE, PRINTER, HISTORY_LIST, CACHE, MOBILE, FTP, SNAPSHOT, PERSONAL_VIEW, SHARED_LINK, UNSUPPORTED], delivery_expiration_date(str): expiration date of the subscription, format should be yyyy-MM-dd, contact_security(bool): whether to use contact security for each contact group member, filename(str): the filename that will be delivered when the subscription is executed, compress(bool): whether to compress the file, space_delimiter(str): space delimiter, email_subject(str): email subject associated with the subscription, email_message(str): email body of subscription, email_send_content_as(str,enum): [data, data_and_history_list, data_and_link_and_history_list, link_and_history_list], overwrite_older_version(bool): whether the current subscription will overwrite earlier versions of the same report or document in the history list, zip_filename(str): filename of the compressed content, zip_password_protect(bool): whether to password protect zip file, zip_password(str): optional password for the compressed file, file_burst_sub_folder(str): burst sub folder, printer_copies(int): the number of copies that should be printed, printer_range_start(int): the number indicating the first report page that should be printed, printer_range_end(int): the number indicating the last report page that should be printed, printer_collated(bool): whether the printing should be collated, printer_orientation(str,enum): [ PORTRAIT, LANDSCAPE ] printer_use_print_range(bool): whether print range should be used, cache_type(str,enum): [RESERVED, SHORTCUT, BOOKMARK, SHORTCUTWITHBOOKMARK] shortcut_cache_format(str,enum): [RESERVED, JSON, BINARY, BOTH] mobile_client_type(str,enum): [RESERVED, BLACKBERRY, PHONE, TABLET, ANDROID] device_id(str): the mobile target application, do_not_create_update_caches(bool): whether the current subscription will overwrite earlier versions of the same report or document in the history list, re_run_hl(bool): whether subscription will re-run against warehouse """ name = name if len(name) <= 255 else helper.exception_handler( "Name too long. Max name length is 255 characters.") application_id = Subscription._app_id_check(connection, application_id, application_name) # Schedules logic schedules_ids = schedules_ids if isinstance(schedules_ids, list) else [schedules_ids] schedules = [{'id': sch_id} for sch_id in schedules_ids] # Content logic contents = contents if isinstance(contents, list) else [contents] content_type_msg = "Contents must be dictionaries or Content objects." contents = [ content.to_dict(camel_case=True) if isinstance( content, Content) else content if isinstance(content, dict) else helper.exception_handler(content_type_msg, TypeError) for content in contents ] # Delivery logic if delivery: temp_delivery = Delivery.from_dict(delivery) if isinstance( delivery, dict) else delivery else: temp_delivery = Delivery( delivery_mode, delivery_expiration_date, contact_security, email_subject, email_message, filename, compress, None, zip_password, zip_password_protect, space_delimiter, email_send_content_as, overwrite_older_version, file_burst_sub_folder, printer_copies, printer_range_start, printer_range_end, printer_collated, printer_orientation, printer_use_print_range, cache_type, shortcut_cache_format, mobile_client_type, device_id, do_not_create_update_caches, re_run_hl) delivery = temp_delivery.to_dict(camel_case=True) # Recipients logic recipients = Subscription._validate_recipients(connection, contents, recipients, application_id, delivery['mode']) schedules_ids = schedules_ids if isinstance(schedules_ids, list) else [schedules_ids] # Create body body = { "name": name, "allowDeliveryChanges": allow_delivery_changes, "allowPersonalizationChanges": allow_personalization_changes, "allowUnsubscribe": allow_unsubscribe, "sendNow": send_now, "owner": { "id": owner_id }, "schedules": schedules, "contents": contents, "recipients": recipients, "delivery": delivery } body = helper.delete_none_values(body) response = subscriptions.create_subscription(connection, application_id, body) if config.verbose: unpacked_response = response.json() print("Created subscription '{}' with ID: '{}'.".format( name, unpacked_response['id'])) return Subscription.from_dict(connection, response.json(), application_id)
def create( cls, connection: "Connection", name: str, dbms: Union[Dbms, str], description: Optional[str] = None, datasource_type: Optional[Union[str, DatasourceType]] = None, table_prefix: Optional[str] = None, odbc_version: Optional[str] = None, intermediate_store_db_name: Optional[str] = None, intermediate_store_table_space_name: Optional[str] = None, datasource_connection: Union[str, DatasourceConnection, None] = None, database_type: str = None, database_version: str = None, primary_datasource: Union[str, "DatasourceInstance", None] = None, data_mart_datasource: Union[str, "DatasourceInstance", None] = None ) -> Optional["DatasourceInstance"]: """Create a new DatasourceInstance object on I-Server. Args: connection: MicroStrategy connection object returned by `connection.Connection()`. name: Datasource name dbms: The database management system (DBMS) object or id description: Datasource description datasource_type: DatasourceType Enum (reserved, normal, data_import, data_import_primary) table_prefix: Table prefix odbc_version: Odbc version ENUM (version3x, version2x) intermediate_store_db_name: Intermediate store DBName intermediate_store_table_space_name: intermediate store table space name datasource_connection: `DatasourceConnection` object or ID database_type: Database type database_version: Database version primary_datasource: `DatasourceInstance` object or ID data_mart_datasource: `DatasourceInstance` object or ID Returns: DatasourceInstance object. """ dbms_id = get_objects_id(dbms, Dbms) connection_id = get_objects_id(datasource_connection, DatasourceConnection) primary_datasource_id = get_objects_id(primary_datasource, cls) data_mart_datasource_id = get_objects_id(data_mart_datasource, cls) database = { "type": database_type, "version": database_version, "connection": { "id": connection_id } } if primary_datasource_id: database["primaryDatasource"] = {"id": primary_datasource_id} if data_mart_datasource_id: database["dataMartDatasource"] = {"id": data_mart_datasource_id} body = { "name": name, "database": database, "description": description, "datasourceType": get_enum_val(datasource_type, DatasourceType), "tablePrefix": table_prefix, "odbcVersion": odbc_version, "intermediateStoreDbName": intermediate_store_db_name, "intermediateStoreTableSpaceName": intermediate_store_table_space_name, "dbms": { "id": dbms_id } } body = helper.delete_none_values(body) response = datasources.create_datasource_instance(connection, body).json() if config.verbose: logger.info( f"Successfully created datasource instance named: '{response.get('name')}' " f"with ID: '{response.get('id')}'") return cls.from_dict(source=response, connection=connection)
def create( cls, connection: Connection, name: str, schedule_type: Union[ScheduleType, str], start_date: Union[str, datetime], description: Optional[str] = None, stop_date: Optional[Union[str, datetime]] = None, event_id: Optional[str] = None, time: Optional[ScheduleTime] = None, recurrence_pattern: Optional[Union[ScheduleEnums.RecurrencePattern, str]] = None, execution_pattern: Optional[Union[ScheduleEnums.ExecutionPattern, str]] = None, execution_time: Optional[str] = None, start_time: Optional[str] = None, stop_time: Optional[str] = None, execution_repeat_interval: Optional[int] = None, daily_pattern: Optional[Union[ScheduleEnums.DailyPattern, str]] = None, repeat_interval: Optional[int] = None, days_of_week: Optional[Union[List[ScheduleEnums.DaysOfWeek], List[str]]] = None, day: Optional[int] = None, month: Optional[int] = None, week_offset: Optional[Union[ScheduleEnums.WeekOffset, str]] = None, day_of_week: Optional[Union[ScheduleEnums.DaysOfWeek, str]] = None, weekday_off_set: Optional[str] = None, days_of_month: Optional[List[str]] = None, monthly_pattern: Optional[Union[ScheduleEnums.MonthlyPattern, str]] = None, yearly_pattern: Optional[Union[ScheduleEnums.YearlyPattern, str]] = None): """Create a Schedule using provided parameters as data. Args: recurrence_pattern (ScheduleEnums.RecurrencePattern, optional): The recurrence pattern of the schedule. Possible values are DAILY, WEEKLY, MONTHLY, YEARLY. Defaults to None. execution_pattern (ScheduleEnums.ExecutionPattern, optional): The execution pattern of the schedule. Possible values are ONCE, REPEAT. Defaults to None. execution_time (str, optional): The execution time of the execution day, if execution_pattern is ONCE. Format should be HH:mm:ss. Defaults to None. start_time (str, optional): The start time of the execution day, if execution_pattern is REPEAT. Format should be HH:mm:ss. Defaults to None. stop_time (str, optional): The stop time of the execution day, if execution_pattern is REPEAT.Format should be HH:mm:ss. Defaults to None. execution_repeat_interval (int, optional): The repeat interval of minutes of the execution day, if execution_pattern is REPEAT. Defaults to None. daily_pattern (ScheduleEnums.DailyPattern, optional): The daily recurrence pattern of the schedule. Possible values are DAY, WEEKDAY. Defaults to None. repeat_interval (int, optional): The repeat interval of days of daily schedule, if daily_pattern is DAY. Defaults to None. day (int, optional): The day in month of monthly schedule, if monthly_pattern is DAY or, The day in month of yearly schedule, if yearly_pattern is DAY. Defaults to None. month (int, optional): The month in year of yearly schedule. Defaults to None. week_offset (ScheduleEnums.WeekOffset, optional): The week offset in month of monthly schedule, if monthly_pattern is DAY_OF_WEEK or, The week offset in year of yearly schedule, if yearly_pattern is DAY_OF_WEEK. Possible values are FIRST, SECOND, THIRD, FOURTH, LAST. Defaults to None. day_of_week (ScheduleEnums.DaysOfWeek, optional): The days of week of weekly schedule or, The day of week in month of monthly schedule, if monthly_pattern is DAY_OF_WEEK or, The day of week in year of yearly schedule, if yearly_pattern is DAY_OF_WEEK. Possible values are: MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY. Defaults to None. weekday_offset (ScheduleEnums.WeekdayOffset, optional): The weekday offset in month of monthly schedule, if monthly_pattern is WEEKDAY. Defaults to None. days_of_month (List[str], optional): The days of month of monthly schedule, if monthly_pattern is DAYS_OF_MONTH. Must be provided as a list of one or more stringified digits (from '1' to '31'). Defaults to None. monthly_pattern (ScheduleEnums.MonthlyPattern, optional): The monthly recurrence pattern of the schedule. Possible values are: DAY, DAY_OF_WEEK, WEEKDAY, LAST_DAY, DAYS_OF_MONTH. Defaults to None. yearly_pattern (ScheduleEnums.YearlyPattern, optional): The yearly recurrence pattern of the schedule. Possible values are DAY, DAY_OF_WEEK. Defaults to None. Returns: Schedule object with provided parameters. """ time_kwargs = { key: val for key, val in locals().items() if val is not None and key not in [ 'event_id', 'connection', 'description', 'name', 'schedule_type', 'start_date', 'stop_date', 'time', 'self', 'cls' ] } # Event based or Time based logic if schedule_type == cls.ScheduleType.EVENT_BASED: execution_details = {'type': 'event', 'content': {'id': event_id}} elif schedule_type == cls.ScheduleType.TIME_BASED: if time is None: time = ScheduleTime.from_details(**time_kwargs) execution_details = {'type': 'time', 'content': time.to_dict()} # Datetime dates to string format conversion start_date = map_datetime_to_str(name='start_date', date=start_date, string_to_date_map=cls._FROM_DICT_MAP) stop_date = map_datetime_to_str(name='stop_date', date=stop_date, string_to_date_map=cls._FROM_DICT_MAP) # Create body and send request body = { 'name': name, 'description': description, 'schedule_type': get_enum_val(schedule_type, cls.ScheduleType), 'start_date': start_date, 'stop_date': stop_date, execution_details['type']: execution_details['content'] } body = helper.delete_none_values(body) body = helper.snake_to_camel(body) # Response is already unpacked in wrapper response = schedules.create_schedule(connection, body) response = response.json() if config.verbose: logger.info(f"Created schedule '{name}' with ID: {response['id']}") return Schedule.from_dict(source=response, connection=connection)
def __create( # NOSONAR cls, # NOSONAR connection: Connection, name: str, project_id: Optional[str] = None, project_name: Optional[str] = None, allow_delivery_changes: Optional[bool] = None, allow_personalization_changes: Optional[bool] = None, allow_unsubscribe: Optional[bool] = None, send_now: Optional[bool] = None, owner_id: Optional[str] = None, schedules: Optional[Union[str, List[str], Schedule, List[Schedule]]] = None, contents: Content = None, recipients: Union[List[dict], List[str]] = None, delivery: Union[Delivery, dict] = None, delivery_mode: str = Delivery.DeliveryMode.EMAIL, delivery_expiration_date: Optional[str] = None, contact_security: bool = True, filename: Optional[str] = None, compress: bool = False, space_delimiter: Optional[str] = None, email_subject: Optional[str] = None, email_message: Optional[str] = None, email_send_content_as: str = SendContentAs.DATA, overwrite_older_version: bool = False, zip_filename: Optional[str] = None, zip_password_protect: Optional[bool] = None, zip_password: Optional[str] = None, file_burst_sub_folder: Optional[str] = None, printer_copies: int = 1, printer_range_start: int = 0, printer_range_end: int = 0, printer_collated: bool = True, printer_orientation: str = Orientation.PORTRAIT, printer_use_print_range: bool = False, cache_cache_type: Union[CacheType, str] = CacheType.RESERVED, cache_shortcut_cache_format: Union[ ShortcutCacheFormat, str] = ShortcutCacheFormat.RESERVED, mobile_client_type: str = ClientType.RESERVED, device_id: Optional[str] = None, do_not_create_update_caches: bool = True, re_run_hl: bool = True, cache_library_cache_types: List[Union[LibraryCacheTypes, str]] = [ LibraryCacheTypes.WEB ], cache_reuse_dataset_cache: bool = False, cache_is_all_library_users: bool = False, delivery_notification_enabled: bool = False, delivery_personal_notification_address_id: Optional[str] = None): """Creates a subscription Create_Subscription_Outline. Args: connection(Connection): a MicroStrategy connection object name(str): name of the subscription, project_id(str): project ID, project_name(str): project name, allow_delivery_changes(bool): whether the recipients can change the delivery of the subscription, allow_personalization_changes(bool): whether the recipients can personalize the subscription, allow_unsubscribe(bool): whether the recipients can unsubscribe from the subscription, send_now(bool): indicates whether to execute the subscription immediately, owner_id(str): ID of the subscription owner, by default logged in user ID, schedules (Union[str, List[str], Schedule, List[Schedule]]): Schedules IDs or Schedule objects, contents (Content): The content settings. recipients (List[dict],List[str]): list of recipients IDs or dicts, delivery(Union[Delivery,dict]): delivery object or dict delivery_mode(str, enum): the subscription delivery mode [EMAIL, FILE, PRINTER, HISTORY_LIST, CACHE, MOBILE, FTP, SNAPSHOT, PERSONAL_VIEW, SHARED_LINK, UNSUPPORTED], delivery_expiration_date(str): expiration date of the subscription, format should be yyyy-MM-dd, contact_security(bool): whether to use contact security for each contact group member, filename(str): the filename that will be delivered when the subscription is executed, compress(bool): whether to compress the file, space_delimiter(str): space delimiter, email_subject(str): email subject associated with the subscription, email_message(str): email body of subscription, email_send_content_as(str,enum): [data, data_and_history_list, data_and_link_and_history_list, link_and_history_list], overwrite_older_version(bool): whether the current subscription will overwrite earlier versions of the same report or document in the history list, zip_filename(str): filename of the compressed content, zip_password_protect(bool): whether to password protect zip file, zip_password(str): optional password for the compressed file, file_burst_sub_folder(str): burst sub folder, printer_copies(int): the number of copies that should be printed, printer_range_start(int): the number indicating the first report page that should be printed, printer_range_end(int): the number indicating the last report page that should be printed, printer_collated(bool): whether the printing should be collated, printer_orientation(str,enum): [ PORTRAIT, LANDSCAPE ] printer_use_print_range(bool): whether print range should be used, cache_cache_type(str,enum): [RESERVED, SHORTCUT, SHORTCUTWITHBOOKMARK] cache_shortcut_cache_format(str,enum):[RESERVED, JSON, BINARY, BOTH] mobile_client_type(str,enum): [RESERVED, BLACKBERRY, PHONE, TABLET, ANDROID] device_id(str): the mobile target project, do_not_create_update_caches(bool): whether the current subscription will overwrite earlier versions of the same report or document in the history list, re_run_hl(bool): whether subscription will re-run against warehouse cache_library_cache_types: Set of library cache types, available types can be web, android, ios cache_reuse_dataset_cache: Whether to reuse dataset cache cache_is_all_library_users: Whether for all library users delivery_notification_enabled: Whether notification is enabled, notification applies to cache delivery_personal_notification_address_id: Notification details """ name = name if len(name) <= 255 else helper.exception_handler( "Name too long. Max name length is 255 characters.") project_id = cls._project_id_check(connection, project_id, project_name) if not schedules: msg = ("Please specify 'schedules' parameter.") helper.exception_handler(msg) schedules = cls.__validate_schedules(schedules=schedules) # Content logic contents = contents if isinstance(contents, list) else [contents] content_type_msg = "Contents must be dictionaries or Content objects." contents = [ content.to_dict(camel_case=True) if isinstance( content, Content) else content if isinstance(content, dict) else helper.exception_handler(content_type_msg, TypeError) for content in contents ] # Delivery logic if delivery: temp_delivery = Delivery.from_dict(delivery) if isinstance( delivery, dict) else delivery else: temp_delivery = Delivery( delivery_mode, delivery_expiration_date, contact_security, email_subject, email_message, filename, compress, None, zip_password, zip_password_protect, space_delimiter, email_send_content_as, overwrite_older_version, file_burst_sub_folder, printer_copies, printer_range_start, printer_range_end, printer_collated, printer_orientation, printer_use_print_range, mobile_client_type, device_id, do_not_create_update_caches, re_run_hl, cache_type=cache_cache_type, shortcut_cache_format=cache_shortcut_cache_format, library_cache_types=cache_library_cache_types, reuse_dataset_cache=cache_reuse_dataset_cache, is_all_library_users=cache_is_all_library_users, notification_enabled=delivery_notification_enabled, personal_notification_address_id= delivery_personal_notification_address_id) delivery = temp_delivery.to_dict(camel_case=True) # Recipients logic recipients = cls._validate_recipients(connection, contents, recipients, project_id, delivery['mode']) # Create body body = { "name": name, "allowDeliveryChanges": allow_delivery_changes, "allowPersonalizationChanges": allow_personalization_changes, "allowUnsubscribe": allow_unsubscribe, "sendNow": send_now, "owner": { "id": owner_id }, "schedules": schedules, "contents": contents, "recipients": recipients, "delivery": delivery } body = helper.delete_none_values(body) response = subscriptions.create_subscription(connection, project_id, body) if config.verbose: unpacked_response = response.json() logger.info( f"Created subscription '{name}' with ID: '{unpacked_response['id']}'." ) return cls.from_dict(response.json(), connection, project_id)
def alter( self, # NOSONAR name: Optional[str] = None, allow_delivery_changes: Optional[bool] = None, allow_personalization_changes: Optional[bool] = None, allow_unsubscribe: Optional[bool] = None, send_now: bool = False, owner_id: Optional[str] = None, schedules: Optional[Union[str, List[str], Schedule, List[Schedule]]] = None, contents: Optional[Content] = None, recipients: Optional[Union[List[str], List[dict]]] = None, delivery: Optional[Union[Delivery, dict]] = None, delivery_mode: Optional[str] = None, custom_msg: Optional[str] = None, delivery_expiration_date: Optional[str] = None, contact_security: Optional[bool] = None, filename: Optional[str] = None, compress: Optional[bool] = None, space_delimiter: Optional[str] = None, email_subject: Optional[str] = None, email_message: Optional[str] = None, email_send_content_as: Optional[str] = None, overwrite_older_version: Optional[bool] = None, zip_filename: Optional[str] = None, zip_password_protect: Optional[bool] = None, zip_password: Optional[str] = None, file_burst_sub_folder: Optional[str] = None, printer_copies: Optional[int] = None, printer_range_start: Optional[int] = None, printer_range_end: Optional[int] = None, printer_collated: Optional[bool] = None, printer_orientation: Optional[str] = None, printer_use_print_range: Optional[bool] = None, cache_cache_type: Optional[str] = None, cache_shortcut_cache_format: Optional[str] = None, mobile_client_type: Optional[str] = None, device_id: Optional[str] = None, do_not_create_update_caches: Optional[bool] = None, re_run_hl: Optional[bool] = None, cache_library_cache_types: List[Union[LibraryCacheTypes, str]] = [ LibraryCacheTypes.WEB ], cache_reuse_dataset_cache: bool = False, cache_is_all_library_users: bool = False, delivery_notification_enabled: bool = False, delivery_personal_notification_address_id: Optional[str] = None): """ Alter subscription. Args: connection(Connection): a MicroStrategy connection object name(str): name of the subscription, project_id(str): project ID, allow_delivery_changes(bool): whether the recipients can change the delivery of the subscription, allow_personalization_changes(bool): whether the recipients can personalize the subscription, allow_unsubscribe(bool): whether the recipients can unsubscribe from the subscription, send_now(bool): indicates whether to execute the subscription immediately, owner_id(str): ID of the subscription owner, by default logged in user ID, schedules (Union[str, List[str], Schedule, List[Schedule]]): Schedules IDs or Schedule objects, contents (Content): The content of the subscription. recipients (Union[List[str], List[dict]]): list of recipients IDs or dicts, delivery_mode(str, enum): the subscription delivery mode [EMAIL, FILE, PRINTER, HISTORY_LIST, CACHE, MOBILE, FTP, SNAPSHOT, PERSONAL_VIEW, SHARED_LINK, UNSUPPORTED], delivery_expiration_date(str): expiration date of the subscription, format should be yyyy-MM-dd, contact_security(bool): whether to use contact security for each contact group member, filename(str): the filename that will be delivered when the subscription is executed, compress(bool): whether to compress the file space_delimiter(str): space delimiter, email_subject(str): email subject associated with the subscription, email_message(str): email body of subscription, email_send_content_as(str,enum): [data, data_and_history_list, data_and_link_and_history_list, link_and_history_list], overwrite_older_version(bool): whether the current subscription will overwrite earlier versions of the same report or document in the history list, zip_filename(str): filename of the compressed content, zip_password_protect(bool): whether to password protect zip file, zip_password(str): optional password for the compressed file file_burst_sub_folder(str): burst sub folder, printer_copies(int): the number of copies that should be printed, printer_range_start(int): the number indicating the first report page that should be printed, printer_range_end(int): the number indicating the last report page that should be printed, printer_collated(bool): whether the printing should be collated, printer_orientation(str,enum): [ PORTRAIT, LANDSCAPE ] printer_use_print_range(bool): whether print range should be used, cache_cache_type(str,enum): [RESERVED, SHORTCUT, SHORTCUTWITHBOOKMARK] cache_shortcut_cache_format(str,enum): [RESERVED, JSON, BINARY, BOTH] mobile_client_type(str,enum): [RESERVED, BLACKBERRY, PHONE, TABLET, ANDROID] device_id(str): the mobile target project, do_not_create_update_caches(bool): whether the current subscription will overwrite earlier versions of the same report or document in the history list, re_run_hl(bool): whether subscription will re-run against warehouse cache_library_cache_types: Set of library cache types, available types can be web, android, ios cache_reuse_dataset_cache: Whether to reuse dataset cache cache_is_all_library_users: Whether for all library users delivery_notification_enabled: Whether notification is enabled, notification applies to cache delivery_personal_notification_address_id: Notification details """ # Schedules logic schedules = self.__validate_schedules(schedules=schedules) if not schedules: schedules = [{'id': sch.id} for sch in self.schedules] # Content logic if contents: contents = self.__validate_contents(contents) else: contents = [cont.to_dict() for cont in self.contents] # Delivery logic if delivery: temp_delivery = (Delivery.from_dict(delivery) if isinstance( delivery, dict) else delivery) else: temp_delivery = self.__change_delivery_properties( delivery_mode, delivery_expiration_date, contact_security, email_subject, email_message, filename, compress, None, zip_filename, zip_password, zip_password_protect, space_delimiter, email_send_content_as, overwrite_older_version, file_burst_sub_folder, printer_copies, printer_range_start, printer_range_end, printer_collated, printer_orientation, printer_use_print_range, client_type=mobile_client_type, device_id=device_id, do_not_create_update_caches=do_not_create_update_caches, re_run_hl=re_run_hl, cache_type=cache_cache_type, shortcut_cache_format=cache_shortcut_cache_format, library_cache_types=cache_library_cache_types, reuse_dataset_cache=cache_reuse_dataset_cache, is_all_library_users=cache_is_all_library_users, notification_enabled=delivery_notification_enabled, personal_notification_address_id= delivery_personal_notification_address_id) delivery = temp_delivery.to_dict(camel_case=True) # Recipients logic recipients = self.__is_val_changed(recipients=recipients) recipients = Subscription._validate_recipients(self.connection, contents, recipients, self.project_id, delivery['mode']) body = { "name": self.__is_val_changed(name=name), "allowDeliveryChanges": self.__is_val_changed( allow_delivery_changes=allow_delivery_changes), "allowPersonalizationChanges": self.__is_val_changed( allow_personalization_changes=allow_personalization_changes), "allowUnsubscribe": self.__is_val_changed(allow_unsubscribe=allow_unsubscribe), "sendNow": send_now, 'owner': { 'id': self.__is_val_changed(nested=self.owner.id, owner_id=owner_id) }, "schedules": schedules, "contents": contents, "recipients": recipients, "delivery": delivery, } body = helper.delete_none_values(body) response = subscriptions.update_subscription(self.connection, self.id, self.project_id, body) if response.ok: response = response.json() response = helper.camel_to_snake(response) self._set_object_attributes(**response) if config.verbose: msg = f"Updated subscription '{self.name}' with ID: {self.id}." msg = custom_msg if custom_msg else msg logger.info(msg)
def create(cls, connection: "Connection", name: str, sub_type: Union[str, UserHierarchySubType], destination_folder_id: str, attributes: Union[List[HierarchyAttribute], List[dict]], use_as_drill_hierarchy: bool = True, description: str = None, is_embedded: bool = False, primary_locale: str = None, relationships: Union[List[HierarchyRelationship], List[dict]] = None): """Create a new user hierarchy in a specific project. Args: connection: MicroStrategy connection object returned by `connection.Connection()`. name (str): name of a new user hierarchy. sub_type (str, enum): string literal used to identify the type of a metadata object, UserHierarchySubType enum attributes (list): the list of attributes that do have any relationships currently destination_folder_id (str): a globally unique identifier used to distinguish between metadata objects within the same project use_as_drill_hierarchy (bool, optional): whether this user hierarchy is used as drill hierarchy description (str, optional): optional description of a new user hierarchy is_embedded (bool, optional): if true indicates that the target object of this reference is embedded within this object primary_locale (str, optional): the primary locale of the object, in the IETF BCP 47 language tag format, such as "en-US" relationships (list, optional): the list of attribute relationships stored in the system hierarchy Returns: UserHierarchy object """ attributes = [ attr.to_dict() if isinstance(attr, HierarchyAttribute) else attr for attr in attributes ] relationships = [ rel.to_dict() if isinstance(rel, HierarchyRelationship) else rel for rel in relationships ] if relationships else None body = { "information": { "name": name, "description": description, "subType": get_enum_val(sub_type, UserHierarchySubType), "destinationFolderId": destination_folder_id, "isEmbedded": is_embedded, "primaryLocale": primary_locale }, "useAsDrillHierarchy": use_as_drill_hierarchy, "primaryLocale": primary_locale, "attributes": attributes, "relationships": relationships } body = delete_none_values(body) response = user_hierarchies.create_user_hierarchy(connection, body).json() if config.verbose: logger.info( f"Successfully created user hierarchy named: '{response['name']}' " f"with ID: '{response['id']}'") return cls.from_dict(source=response, connection=connection)
def create(cls, connection: Connection, username: str, full_name: str, password: Optional[str] = None, description: Optional[str] = None, enabled: bool = True, password_modifiable: bool = True, password_expiration_date: Optional[Union[str, datetime]] = None, require_new_password: bool = True, standard_auth: bool = True, ldapdn: Optional[str] = None, trust_id: Optional[str] = None, database_auth_login: Optional[str] = None, memberships: Optional[list] = None) -> "User": """Create a new user on the I-Server. Returns User object. Args: connection: MicroStrategy connection object returned by `connection.Connection()` username: username of user full_name: user full name password: user password description: user description enabled: specifies if user is allowed to log in password_modifiable: Specifies if user password can be modified password_expiration_date: Expiration date of user password either as a datetime or string: "yyyy-MM-dd HH:mm:ss" in UTC require_new_password: Specifies if user is required to provide a new password. standard_auth: Specifies whether standard authentication is allowed for user. ldapdn: User's LDAP distinguished name trust_id: Unique user ID provided by trusted authentication provider database_auth_login: Database Authentication Login memberships: specify User Group IDs which User will be member off. """ password_expiration_date = time_helper.map_datetime_to_str( name='password_expiration_date', date=password_expiration_date, string_to_date_map=cls._FROM_DICT_MAP) body = { "username": username, "fullName": full_name, "description": description, "password": password, "enabled": enabled, "passwordModifiable": password_modifiable, "passwordExpirationDate": password_expiration_date, "requireNewPassword": require_new_password, "standardAuth": standard_auth, "ldapdn": ldapdn, "trustId": trust_id, "databaseAuthLogin": database_auth_login, "memberships": memberships } body = helper.delete_none_values(body) response = users.create_user(connection, body, username).json() if config.verbose: logger.info( f"Successfully created user named: '{response.get('username')}' " f"with ID: '{response.get('id')}'") return cls.from_dict(source=response, connection=connection)