wxcli 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wxcli/__init__.py +4 -0
- wxcli/_playbook/.claude/agents/migration-advisor.md +239 -0
- wxcli/_playbook/.claude/agents/wxc-calling-builder.md +946 -0
- wxcli/_playbook/.claude/rules/cleanup.md +29 -0
- wxcli/_playbook/.claude/rules/cucm-migration.md +58 -0
- wxcli/_playbook/.claude/rules/org-health.md +14 -0
- wxcli/_playbook/.claude/settings.json +8 -0
- wxcli/_playbook/.claude/skills/audit-compliance/SKILL.md +515 -0
- wxcli/_playbook/.claude/skills/call-control/SKILL.md +747 -0
- wxcli/_playbook/.claude/skills/configure-features/SKILL.md +623 -0
- wxcli/_playbook/.claude/skills/configure-routing/SKILL.md +627 -0
- wxcli/_playbook/.claude/skills/contact-center/SKILL.md +1181 -0
- wxcli/_playbook/.claude/skills/cucm-migrate/SKILL.md +820 -0
- wxcli/_playbook/.claude/skills/customer-assist/SKILL.md +443 -0
- wxcli/_playbook/.claude/skills/device-platform/SKILL.md +407 -0
- wxcli/_playbook/.claude/skills/manage-call-settings/SKILL.md +757 -0
- wxcli/_playbook/.claude/skills/manage-devices/SKILL.md +790 -0
- wxcli/_playbook/.claude/skills/manage-identity/SKILL.md +638 -0
- wxcli/_playbook/.claude/skills/manage-licensing/SKILL.md +528 -0
- wxcli/_playbook/.claude/skills/manage-meetings/SKILL.md +708 -0
- wxcli/_playbook/.claude/skills/messaging-bots/SKILL.md +365 -0
- wxcli/_playbook/.claude/skills/messaging-spaces/SKILL.md +520 -0
- wxcli/_playbook/.claude/skills/org-health/SKILL.md +159 -0
- wxcli/_playbook/.claude/skills/provision-calling/SKILL.md +421 -0
- wxcli/_playbook/.claude/skills/query-live/SKILL.md +183 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-flow-trace.md +223 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-history.md +44 -0
- wxcli/_playbook/.claude/skills/query-live/domains/features.md +169 -0
- wxcli/_playbook/.claude/skills/query-live/domains/numbers.md +93 -0
- wxcli/_playbook/.claude/skills/query-live/domains/people-and-settings.md +146 -0
- wxcli/_playbook/.claude/skills/query-live/domains/routing.md +124 -0
- wxcli/_playbook/.claude/skills/reporting/SKILL.md +501 -0
- wxcli/_playbook/.claude/skills/reporting/references/cdr-recipes.md +1628 -0
- wxcli/_playbook/.claude/skills/reporting-cc/SKILL.md +251 -0
- wxcli/_playbook/.claude/skills/reporting-meetings/SKILL.md +290 -0
- wxcli/_playbook/.claude/skills/teardown/SKILL.md +214 -0
- wxcli/_playbook/.claude/skills/video-mesh/SKILL.md +379 -0
- wxcli/_playbook/.claude/skills/wxc-calling-debug/SKILL.md +475 -0
- wxcli/_playbook/CLAUDE.md +373 -0
- wxcli/_playbook/docs/reference/CLAUDE.md +25 -0
- wxcli/_playbook/docs/reference/admin-apps-data.md +643 -0
- wxcli/_playbook/docs/reference/admin-audit-security.md +322 -0
- wxcli/_playbook/docs/reference/admin-hybrid.md +383 -0
- wxcli/_playbook/docs/reference/admin-identity-scim.md +1007 -0
- wxcli/_playbook/docs/reference/admin-licensing.md +414 -0
- wxcli/_playbook/docs/reference/admin-org-management.md +586 -0
- wxcli/_playbook/docs/reference/admin-partner.md +357 -0
- wxcli/_playbook/docs/reference/archive/wxc-sdk-patterns.md +1229 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-advanced.md +835 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-core.md +743 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-devices-workspaces.md +1305 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-features.md +849 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-locations.md +938 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-person.md +1255 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-routing.md +1262 -0
- wxcli/_playbook/docs/reference/authentication.md +965 -0
- wxcli/_playbook/docs/reference/call-control.md +1205 -0
- wxcli/_playbook/docs/reference/call-features-additional.md +2541 -0
- wxcli/_playbook/docs/reference/call-features-major.md +1320 -0
- wxcli/_playbook/docs/reference/call-routing.md +2304 -0
- wxcli/_playbook/docs/reference/contact-center-analytics.md +1049 -0
- wxcli/_playbook/docs/reference/contact-center-core.md +1614 -0
- wxcli/_playbook/docs/reference/contact-center-journey.md +457 -0
- wxcli/_playbook/docs/reference/contact-center-routing.md +1138 -0
- wxcli/_playbook/docs/reference/devices-core.md +1869 -0
- wxcli/_playbook/docs/reference/devices-dect.md +1150 -0
- wxcli/_playbook/docs/reference/devices-platform.md +467 -0
- wxcli/_playbook/docs/reference/devices-workspaces.md +1426 -0
- wxcli/_playbook/docs/reference/emergency-services.md +1122 -0
- wxcli/_playbook/docs/reference/location-calling-core.md +2037 -0
- wxcli/_playbook/docs/reference/location-calling-media.md +1334 -0
- wxcli/_playbook/docs/reference/location-recording-advanced.md +1482 -0
- wxcli/_playbook/docs/reference/meetings-content.md +473 -0
- wxcli/_playbook/docs/reference/meetings-core.md +903 -0
- wxcli/_playbook/docs/reference/meetings-infrastructure.md +899 -0
- wxcli/_playbook/docs/reference/meetings-settings.md +850 -0
- wxcli/_playbook/docs/reference/messaging-bots.md +1091 -0
- wxcli/_playbook/docs/reference/messaging-spaces.md +695 -0
- wxcli/_playbook/docs/reference/person-call-settings-behavior.md +1639 -0
- wxcli/_playbook/docs/reference/person-call-settings-handling.md +1394 -0
- wxcli/_playbook/docs/reference/person-call-settings-media.md +1898 -0
- wxcli/_playbook/docs/reference/person-call-settings-permissions.md +1329 -0
- wxcli/_playbook/docs/reference/provisioning.md +1366 -0
- wxcli/_playbook/docs/reference/reporting-analytics.md +1318 -0
- wxcli/_playbook/docs/reference/self-service-call-settings.md +1020 -0
- wxcli/_playbook/docs/reference/virtual-lines.md +1132 -0
- wxcli/_playbook/docs/reference/webhooks-events.md +1444 -0
- wxcli/_playbook/docs/reference/wxcadm-xsi-realtime.md +953 -0
- wxcli/_version.py +24 -0
- wxcli/auth.py +137 -0
- wxcli/commands/__init__.py +0 -0
- wxcli/commands/_registry.py +181 -0
- wxcli/commands/activation_email.py +103 -0
- wxcli/commands/admin_recordings.py +585 -0
- wxcli/commands/analytics.py +105 -0
- wxcli/commands/announcement_playlists.py +219 -0
- wxcli/commands/announcements.py +519 -0
- wxcli/commands/archive_users.py +36 -0
- wxcli/commands/attachment_actions.py +60 -0
- wxcli/commands/audit_events.py +83 -0
- wxcli/commands/authorizations.py +113 -0
- wxcli/commands/auto_attendant.py +642 -0
- wxcli/commands/broadworks_billing_reports.py +126 -0
- wxcli/commands/broadworks_enterprises.py +160 -0
- wxcli/commands/broadworks_subscribers.py +319 -0
- wxcli/commands/broadworks_workspaces.py +108 -0
- wxcli/commands/call_controls.py +1304 -0
- wxcli/commands/call_park.py +494 -0
- wxcli/commands/call_pickup.py +229 -0
- wxcli/commands/call_queue.py +1878 -0
- wxcli/commands/call_recording.py +707 -0
- wxcli/commands/call_routing.py +1610 -0
- wxcli/commands/call_settings_for_me_phase_5.py +212 -0
- wxcli/commands/caller_reputation.py +169 -0
- wxcli/commands/calling_service.py +305 -0
- wxcli/commands/cc_address_book.py +770 -0
- wxcli/commands/cc_agent_greetings.py +242 -0
- wxcli/commands/cc_agent_summaries.py +39 -0
- wxcli/commands/cc_agent_wellbeing.py +216 -0
- wxcli/commands/cc_agents.py +425 -0
- wxcli/commands/cc_ai_assistant.py +55 -0
- wxcli/commands/cc_ai_feature.py +294 -0
- wxcli/commands/cc_audio_files.py +149 -0
- wxcli/commands/cc_auto_csat.py +311 -0
- wxcli/commands/cc_aux_code.py +458 -0
- wxcli/commands/cc_business_hour.py +353 -0
- wxcli/commands/cc_call_monitoring.py +228 -0
- wxcli/commands/cc_callbacks.py +194 -0
- wxcli/commands/cc_campaign.py +212 -0
- wxcli/commands/cc_captures.py +39 -0
- wxcli/commands/cc_contact_list.py +169 -0
- wxcli/commands/cc_contact_number.py +295 -0
- wxcli/commands/cc_data_sources.py +235 -0
- wxcli/commands/cc_desktop_layout.py +380 -0
- wxcli/commands/cc_desktop_profile.py +322 -0
- wxcli/commands/cc_dial_number.py +511 -0
- wxcli/commands/cc_dial_plan.py +347 -0
- wxcli/commands/cc_dnc.py +101 -0
- wxcli/commands/cc_entry_point.py +545 -0
- wxcli/commands/cc_ewt.py +51 -0
- wxcli/commands/cc_flow.py +477 -0
- wxcli/commands/cc_global_vars.py +430 -0
- wxcli/commands/cc_holiday_list.py +335 -0
- wxcli/commands/cc_journey.py +1261 -0
- wxcli/commands/cc_legacy_flows.py +49 -0
- wxcli/commands/cc_multimedia_profile.py +436 -0
- wxcli/commands/cc_notification.py +51 -0
- wxcli/commands/cc_outdial_ani.py +604 -0
- wxcli/commands/cc_overrides.py +341 -0
- wxcli/commands/cc_queue.py +1083 -0
- wxcli/commands/cc_queue_stats.py +55 -0
- wxcli/commands/cc_realtime.py +51 -0
- wxcli/commands/cc_resource_collection.py +312 -0
- wxcli/commands/cc_search.py +46 -0
- wxcli/commands/cc_site.py +400 -0
- wxcli/commands/cc_skill.py +350 -0
- wxcli/commands/cc_skill_profile.py +289 -0
- wxcli/commands/cc_subscriptions.py +426 -0
- wxcli/commands/cc_summaries.py +130 -0
- wxcli/commands/cc_tasks.py +844 -0
- wxcli/commands/cc_team.py +325 -0
- wxcli/commands/cc_user_profiles.py +349 -0
- wxcli/commands/cc_users.py +701 -0
- wxcli/commands/cc_work_types.py +363 -0
- wxcli/commands/cdr.py +89 -0
- wxcli/commands/classifications.py +38 -0
- wxcli/commands/cleanup.py +1427 -0
- wxcli/commands/client_settings.py +72 -0
- wxcli/commands/conference.py +328 -0
- wxcli/commands/configure.py +72 -0
- wxcli/commands/converged_recordings.py +347 -0
- wxcli/commands/converged_recordings_export.py +310 -0
- wxcli/commands/cq_playlists.py +42 -0
- wxcli/commands/cucm.py +2794 -0
- wxcli/commands/cucm_config.py +129 -0
- wxcli/commands/customer_assist.py +373 -0
- wxcli/commands/data_sources.py +227 -0
- wxcli/commands/dect_devices.py +787 -0
- wxcli/commands/device_configurations.py +77 -0
- wxcli/commands/device_dynamic_settings.py +320 -0
- wxcli/commands/device_settings.py +1489 -0
- wxcli/commands/devices.py +280 -0
- wxcli/commands/domains.py +142 -0
- wxcli/commands/ecm.py +178 -0
- wxcli/commands/emergency_services.py +827 -0
- wxcli/commands/events.py +83 -0
- wxcli/commands/external_voicemail.py +52 -0
- wxcli/commands/groups.py +206 -0
- wxcli/commands/guest_management.py +76 -0
- wxcli/commands/hds.py +340 -0
- wxcli/commands/hot_desk.py +67 -0
- wxcli/commands/hot_desking_members.py +118 -0
- wxcli/commands/hot_desking_portal.py +124 -0
- wxcli/commands/hunt_group.py +577 -0
- wxcli/commands/hybrid_clusters.py +71 -0
- wxcli/commands/hybrid_connectors.py +67 -0
- wxcli/commands/identity_org.py +159 -0
- wxcli/commands/init_playbook.py +155 -0
- wxcli/commands/licenses.py +106 -0
- wxcli/commands/live_monitoring.py +40 -0
- wxcli/commands/location_call_handling.py +577 -0
- wxcli/commands/location_schedules.py +341 -0
- wxcli/commands/location_settings.py +1297 -0
- wxcli/commands/location_voicemail.py +494 -0
- wxcli/commands/locations.py +336 -0
- wxcli/commands/meeting_captions.py +110 -0
- wxcli/commands/meeting_chats.py +63 -0
- wxcli/commands/meeting_invitees.py +234 -0
- wxcli/commands/meeting_messages.py +28 -0
- wxcli/commands/meeting_participants.py +278 -0
- wxcli/commands/meeting_polls.py +111 -0
- wxcli/commands/meeting_preferences.py +515 -0
- wxcli/commands/meeting_qa.py +78 -0
- wxcli/commands/meeting_qualities.py +43 -0
- wxcli/commands/meeting_reports.py +101 -0
- wxcli/commands/meeting_session_types.py +105 -0
- wxcli/commands/meeting_site.py +57 -0
- wxcli/commands/meeting_slido.py +44 -0
- wxcli/commands/meeting_summaries.py +92 -0
- wxcli/commands/meeting_tracking_codes.py +233 -0
- wxcli/commands/meeting_transcripts.py +230 -0
- wxcli/commands/meetings.py +1997 -0
- wxcli/commands/memberships.py +164 -0
- wxcli/commands/messages.py +213 -0
- wxcli/commands/mode_management.py +244 -0
- wxcli/commands/my_call_settings.py +3577 -0
- wxcli/commands/numbers.py +405 -0
- wxcli/commands/operating_modes.py +410 -0
- wxcli/commands/org_contacts.py +284 -0
- wxcli/commands/org_health_cli.py +55 -0
- wxcli/commands/org_settings.py +71 -0
- wxcli/commands/organizations.py +83 -0
- wxcli/commands/paging_group.py +257 -0
- wxcli/commands/partner_admins.py +141 -0
- wxcli/commands/partner_reports.py +188 -0
- wxcli/commands/partner_tags.py +216 -0
- wxcli/commands/people.py +279 -0
- wxcli/commands/person_call_settings.py +71 -0
- wxcli/commands/pstn.py +280 -0
- wxcli/commands/recording_report.py +154 -0
- wxcli/commands/report_templates.py +38 -0
- wxcli/commands/reports.py +144 -0
- wxcli/commands/resource_group_memberships.py +160 -0
- wxcli/commands/resource_groups.py +67 -0
- wxcli/commands/roles.py +63 -0
- wxcli/commands/room_tabs.py +160 -0
- wxcli/commands/rooms.py +225 -0
- wxcli/commands/scim_bulk.py +46 -0
- wxcli/commands/scim_groups.py +246 -0
- wxcli/commands/scim_schemas.py +82 -0
- wxcli/commands/scim_users.py +283 -0
- wxcli/commands/security_audit.py +54 -0
- wxcli/commands/service_apps.py +51 -0
- wxcli/commands/single_number_reach.py +209 -0
- wxcli/commands/team_memberships.py +155 -0
- wxcli/commands/teams.py +153 -0
- wxcli/commands/ucm_profile.py +42 -0
- wxcli/commands/update.py +219 -0
- wxcli/commands/user_settings.py +5116 -0
- wxcli/commands/video_mesh.py +1090 -0
- wxcli/commands/virtual_extensions.py +502 -0
- wxcli/commands/virtual_line_settings.py +2072 -0
- wxcli/commands/webhooks.py +176 -0
- wxcli/commands/wholesale_billing_reports.py +147 -0
- wxcli/commands/wholesale_provisioning.py +523 -0
- wxcli/commands/workspace_locations.py +339 -0
- wxcli/commands/workspace_metrics.py +103 -0
- wxcli/commands/workspace_personalization.py +70 -0
- wxcli/commands/workspace_settings.py +3347 -0
- wxcli/commands/workspaces.py +279 -0
- wxcli/commands/xapi.py +114 -0
- wxcli/config.py +139 -0
- wxcli/errors.py +77 -0
- wxcli/main.py +210 -0
- wxcli/migration/CLAUDE.md +106 -0
- wxcli/migration/__init__.py +1 -0
- wxcli/migration/advisory/CLAUDE.md +196 -0
- wxcli/migration/advisory/__init__.py +46 -0
- wxcli/migration/advisory/advisor.py +107 -0
- wxcli/migration/advisory/advisory_patterns.py +2552 -0
- wxcli/migration/advisory/recommendation_rules.py +835 -0
- wxcli/migration/cucm/CLAUDE.md +74 -0
- wxcli/migration/cucm/__init__.py +5 -0
- wxcli/migration/cucm/connection.py +265 -0
- wxcli/migration/cucm/discovery.py +225 -0
- wxcli/migration/cucm/extractors/__init__.py +1 -0
- wxcli/migration/cucm/extractors/announcements.py +92 -0
- wxcli/migration/cucm/extractors/base.py +90 -0
- wxcli/migration/cucm/extractors/device_profiles.py +98 -0
- wxcli/migration/cucm/extractors/devices.py +193 -0
- wxcli/migration/cucm/extractors/e911.py +103 -0
- wxcli/migration/cucm/extractors/features.py +309 -0
- wxcli/migration/cucm/extractors/helpers.py +73 -0
- wxcli/migration/cucm/extractors/informational.py +295 -0
- wxcli/migration/cucm/extractors/locations.py +221 -0
- wxcli/migration/cucm/extractors/moh.py +100 -0
- wxcli/migration/cucm/extractors/remote_destinations.py +96 -0
- wxcli/migration/cucm/extractors/routing.py +493 -0
- wxcli/migration/cucm/extractors/shared_lines.py +146 -0
- wxcli/migration/cucm/extractors/templates.py +229 -0
- wxcli/migration/cucm/extractors/tier4.py +173 -0
- wxcli/migration/cucm/extractors/users.py +240 -0
- wxcli/migration/cucm/extractors/voicemail.py +243 -0
- wxcli/migration/cucm/extractors/workspaces.py +88 -0
- wxcli/migration/cucm/unity_connection.py +304 -0
- wxcli/migration/execute/CLAUDE.md +372 -0
- wxcli/migration/execute/__init__.py +303 -0
- wxcli/migration/execute/batch.py +277 -0
- wxcli/migration/execute/dependency.py +483 -0
- wxcli/migration/execute/engine.py +964 -0
- wxcli/migration/execute/handlers.py +2232 -0
- wxcli/migration/execute/planner.py +1939 -0
- wxcli/migration/execute/runtime.py +571 -0
- wxcli/migration/export/CLAUDE.md +49 -0
- wxcli/migration/export/__init__.py +8 -0
- wxcli/migration/export/csv_export.py +126 -0
- wxcli/migration/export/deployment_plan.py +479 -0
- wxcli/migration/export/json_export.py +60 -0
- wxcli/migration/models.py +941 -0
- wxcli/migration/phone_models.py +50 -0
- wxcli/migration/preflight/CLAUDE.md +52 -0
- wxcli/migration/preflight/__init__.py +89 -0
- wxcli/migration/preflight/checks.py +911 -0
- wxcli/migration/preflight/runner.py +293 -0
- wxcli/migration/rate_limiter.py +144 -0
- wxcli/migration/report/CLAUDE.md +245 -0
- wxcli/migration/report/__init__.py +7 -0
- wxcli/migration/report/appendix.py +2437 -0
- wxcli/migration/report/assembler.py +183 -0
- wxcli/migration/report/charts.py +263 -0
- wxcli/migration/report/executive.py +776 -0
- wxcli/migration/report/explainer.py +704 -0
- wxcli/migration/report/helpers.py +74 -0
- wxcli/migration/report/ingest.py +152 -0
- wxcli/migration/report/notice_templates.py +192 -0
- wxcli/migration/report/score.py +375 -0
- wxcli/migration/report/styles.py +1052 -0
- wxcli/migration/report/user_diff.py +1052 -0
- wxcli/migration/report/user_notice.py +425 -0
- wxcli/migration/state.py +139 -0
- wxcli/migration/store.py +860 -0
- wxcli/migration/transform/CLAUDE.md +107 -0
- wxcli/migration/transform/__init__.py +12 -0
- wxcli/migration/transform/analysis_pipeline.py +453 -0
- wxcli/migration/transform/analyzers/__init__.py +142 -0
- wxcli/migration/transform/analyzers/css_permission.py +189 -0
- wxcli/migration/transform/analyzers/css_routing.py +335 -0
- wxcli/migration/transform/analyzers/device_compatibility.py +122 -0
- wxcli/migration/transform/analyzers/dn_ambiguity.py +131 -0
- wxcli/migration/transform/analyzers/duplicate_user.py +221 -0
- wxcli/migration/transform/analyzers/extension_conflict.py +173 -0
- wxcli/migration/transform/analyzers/feature_approximation.py +227 -0
- wxcli/migration/transform/analyzers/layout_overflow.py +174 -0
- wxcli/migration/transform/analyzers/location_ambiguity.py +184 -0
- wxcli/migration/transform/analyzers/missing_data.py +300 -0
- wxcli/migration/transform/analyzers/selective_call_handling.py +394 -0
- wxcli/migration/transform/analyzers/shared_line.py +170 -0
- wxcli/migration/transform/analyzers/voicemail_compatibility.py +267 -0
- wxcli/migration/transform/analyzers/workspace_license.py +212 -0
- wxcli/migration/transform/cross_reference.py +1136 -0
- wxcli/migration/transform/cucm_pattern.py +246 -0
- wxcli/migration/transform/decisions.py +301 -0
- wxcli/migration/transform/e164.py +145 -0
- wxcli/migration/transform/engine.py +256 -0
- wxcli/migration/transform/mappers/CLAUDE.md +123 -0
- wxcli/migration/transform/mappers/__init__.py +76 -0
- wxcli/migration/transform/mappers/announcement_mapper.py +122 -0
- wxcli/migration/transform/mappers/base.py +190 -0
- wxcli/migration/transform/mappers/button_template_mapper.py +186 -0
- wxcli/migration/transform/mappers/call_forwarding_mapper.py +228 -0
- wxcli/migration/transform/mappers/call_settings_mapper.py +144 -0
- wxcli/migration/transform/mappers/css_mapper.py +868 -0
- wxcli/migration/transform/mappers/dect_mapper.py +367 -0
- wxcli/migration/transform/mappers/device_layout_mapper.py +289 -0
- wxcli/migration/transform/mappers/device_mapper.py +227 -0
- wxcli/migration/transform/mappers/device_profile_mapper.py +190 -0
- wxcli/migration/transform/mappers/device_settings_mapper.py +464 -0
- wxcli/migration/transform/mappers/e911_mapper.py +129 -0
- wxcli/migration/transform/mappers/ecbn_mapper.py +263 -0
- wxcli/migration/transform/mappers/executive_assistant_mapper.py +156 -0
- wxcli/migration/transform/mappers/feature_mapper.py +1179 -0
- wxcli/migration/transform/mappers/line_mapper.py +310 -0
- wxcli/migration/transform/mappers/location_mapper.py +235 -0
- wxcli/migration/transform/mappers/moh_mapper.py +114 -0
- wxcli/migration/transform/mappers/monitoring_mapper.py +221 -0
- wxcli/migration/transform/mappers/receptionist_mapper.py +245 -0
- wxcli/migration/transform/mappers/routing_mapper.py +821 -0
- wxcli/migration/transform/mappers/snr_mapper.py +201 -0
- wxcli/migration/transform/mappers/softkey_mapper.py +205 -0
- wxcli/migration/transform/mappers/user_mapper.py +264 -0
- wxcli/migration/transform/mappers/voicemail_group_mapper.py +286 -0
- wxcli/migration/transform/mappers/voicemail_mapper.py +514 -0
- wxcli/migration/transform/mappers/workspace_mapper.py +464 -0
- wxcli/migration/transform/normalizers.py +2008 -0
- wxcli/migration/transform/pattern_converter.py +106 -0
- wxcli/migration/transform/pipeline.py +271 -0
- wxcli/migration/transform/rules.py +255 -0
- wxcli/org_health/CLAUDE.md +63 -0
- wxcli/org_health/__init__.py +7 -0
- wxcli/org_health/analyze.py +93 -0
- wxcli/org_health/checks.py +458 -0
- wxcli/org_health/collector.py +62 -0
- wxcli/org_health/models.py +78 -0
- wxcli/org_health/report.py +300 -0
- wxcli/output.py +101 -0
- wxcli-1.2.0.dist-info/METADATA +505 -0
- wxcli-1.2.0.dist-info/RECORD +413 -0
- wxcli-1.2.0.dist-info/WHEEL +5 -0
- wxcli-1.2.0.dist-info/entry_points.txt +2 -0
- wxcli-1.2.0.dist-info/licenses/LICENSE +191 -0
- wxcli-1.2.0.dist-info/scm_file_list.json +751 -0
- wxcli-1.2.0.dist-info/scm_version.json +8 -0
- wxcli-1.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typer
|
|
3
|
+
from wxcli.auth import get_api
|
|
4
|
+
from wxcli.errors import WebexError, handle_rest_error
|
|
5
|
+
from wxcli.output import print_table, print_json
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
app = typer.Typer(help="Manage Webex Meetings meeting-preferences.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("list")
|
|
12
|
+
def cmd_list(
|
|
13
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
14
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. For individual use, if `site"),
|
|
15
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
16
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
17
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
18
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
19
|
+
):
|
|
20
|
+
"""Get Meeting Preference Details."""
|
|
21
|
+
api = get_api(debug=debug)
|
|
22
|
+
url = f"https://webexapis.com/v1/meetingPreferences"
|
|
23
|
+
params = {}
|
|
24
|
+
if user_email is not None:
|
|
25
|
+
params["userEmail"] = user_email
|
|
26
|
+
if site_url is not None:
|
|
27
|
+
params["siteUrl"] = site_url
|
|
28
|
+
if limit > 0:
|
|
29
|
+
params["max"] = limit
|
|
30
|
+
if offset > 0:
|
|
31
|
+
params["start"] = offset
|
|
32
|
+
result = None
|
|
33
|
+
try:
|
|
34
|
+
result = api.session.rest_get(url, params=params)
|
|
35
|
+
except WebexError as e:
|
|
36
|
+
handle_rest_error(e)
|
|
37
|
+
result = result or []
|
|
38
|
+
items = result.get("sites", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
39
|
+
if output == "json":
|
|
40
|
+
print_json(items)
|
|
41
|
+
else:
|
|
42
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@app.command("list-personal-meeting-room")
|
|
47
|
+
def list_personal_meeting_room(
|
|
48
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
49
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. For individual use, if `site"),
|
|
50
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
51
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
52
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
53
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
54
|
+
):
|
|
55
|
+
"""Get Personal Meeting Room Options."""
|
|
56
|
+
api = get_api(debug=debug)
|
|
57
|
+
url = f"https://webexapis.com/v1/meetingPreferences/personalMeetingRoom"
|
|
58
|
+
params = {}
|
|
59
|
+
if user_email is not None:
|
|
60
|
+
params["userEmail"] = user_email
|
|
61
|
+
if site_url is not None:
|
|
62
|
+
params["siteUrl"] = site_url
|
|
63
|
+
if limit > 0:
|
|
64
|
+
params["max"] = limit
|
|
65
|
+
if offset > 0:
|
|
66
|
+
params["start"] = offset
|
|
67
|
+
result = None
|
|
68
|
+
try:
|
|
69
|
+
result = api.session.rest_get(url, params=params)
|
|
70
|
+
except WebexError as e:
|
|
71
|
+
handle_rest_error(e)
|
|
72
|
+
result = result or []
|
|
73
|
+
items = result.get("coHosts", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
74
|
+
if output == "json":
|
|
75
|
+
print_json(items)
|
|
76
|
+
else:
|
|
77
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@app.command("update")
|
|
82
|
+
def update(
|
|
83
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
84
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. For individual use, if `site"),
|
|
85
|
+
topic: str = typer.Option(None, "--topic", help="Personal Meeting Room topic to be updated."),
|
|
86
|
+
host_pin: str = typer.Option(None, "--host-pin", help="Updated PIN for joining the room as host. The host PIN must"),
|
|
87
|
+
enabled_auto_lock: bool = typer.Option(None, "--enabled-auto-lock/--no-enabled-auto-lock", help="Update for option to automatically lock the Personal Room a"),
|
|
88
|
+
auto_lock_minutes: str = typer.Option(None, "--auto-lock-minutes", help="Updated number of minutes after which the Personal Room is l"),
|
|
89
|
+
enabled_notify_host: bool = typer.Option(None, "--enabled-notify-host/--no-enabled-notify-host", help="Update for flag to enable notifying the owner of a Personal"),
|
|
90
|
+
support_co_host: bool = typer.Option(None, "--support-co-host/--no-support-co-host", help="Update for flag allowing other invitees to host a meetingCoH"),
|
|
91
|
+
support_anyone_as_co_host: bool = typer.Option(None, "--support-anyone-as-co-host/--no-support-anyone-as-co-host", help="Whether or not to allow any attendee with a host account on"),
|
|
92
|
+
allow_first_user_to_be_co_host: bool = typer.Option(None, "--allow-first-user-to-be-co-host/--no-allow-first-user-to-be-co-host", help="Whether or not to allow the first attendee with a host accou"),
|
|
93
|
+
allow_authenticated_devices: bool = typer.Option(None, "--allow-authenticated-devices/--no-allow-authenticated-devices", help="Whether or not to allow authenticated video devices in the u"),
|
|
94
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
95
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
96
|
+
):
|
|
97
|
+
"""Update Personal Meeting Room Options\n\nExample --json-body:\n '{"topic":"...","hostPin":"...","enabledAutoLock":true,"autoLockMinutes":0,"enabledNotifyHost":true,"supportCoHost":true,"coHosts":[{"email":"...","displayName":"..."}],"supportAnyoneAsCoHost":true}'."""
|
|
98
|
+
api = get_api(debug=debug)
|
|
99
|
+
url = f"https://webexapis.com/v1/meetingPreferences/personalMeetingRoom"
|
|
100
|
+
params = {}
|
|
101
|
+
if user_email is not None:
|
|
102
|
+
params["userEmail"] = user_email
|
|
103
|
+
if site_url is not None:
|
|
104
|
+
params["siteUrl"] = site_url
|
|
105
|
+
if json_body:
|
|
106
|
+
body = json.loads(json_body)
|
|
107
|
+
else:
|
|
108
|
+
body = {}
|
|
109
|
+
if topic is not None:
|
|
110
|
+
body["topic"] = topic
|
|
111
|
+
if host_pin is not None:
|
|
112
|
+
body["hostPin"] = host_pin
|
|
113
|
+
if enabled_auto_lock is not None:
|
|
114
|
+
body["enabledAutoLock"] = enabled_auto_lock
|
|
115
|
+
if auto_lock_minutes is not None:
|
|
116
|
+
body["autoLockMinutes"] = auto_lock_minutes
|
|
117
|
+
if enabled_notify_host is not None:
|
|
118
|
+
body["enabledNotifyHost"] = enabled_notify_host
|
|
119
|
+
if support_co_host is not None:
|
|
120
|
+
body["supportCoHost"] = support_co_host
|
|
121
|
+
if support_anyone_as_co_host is not None:
|
|
122
|
+
body["supportAnyoneAsCoHost"] = support_anyone_as_co_host
|
|
123
|
+
if allow_first_user_to_be_co_host is not None:
|
|
124
|
+
body["allowFirstUserToBeCoHost"] = allow_first_user_to_be_co_host
|
|
125
|
+
if allow_authenticated_devices is not None:
|
|
126
|
+
body["allowAuthenticatedDevices"] = allow_authenticated_devices
|
|
127
|
+
try:
|
|
128
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
129
|
+
except WebexError as e:
|
|
130
|
+
handle_rest_error(e)
|
|
131
|
+
typer.echo(f"Updated.")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@app.command("show")
|
|
136
|
+
def show(
|
|
137
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
138
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. For individual use, if `site"),
|
|
139
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
140
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
141
|
+
):
|
|
142
|
+
"""Get Audio Options."""
|
|
143
|
+
api = get_api(debug=debug)
|
|
144
|
+
url = f"https://webexapis.com/v1/meetingPreferences/audio"
|
|
145
|
+
params = {}
|
|
146
|
+
if user_email is not None:
|
|
147
|
+
params["userEmail"] = user_email
|
|
148
|
+
if site_url is not None:
|
|
149
|
+
params["siteUrl"] = site_url
|
|
150
|
+
try:
|
|
151
|
+
result = api.session.rest_get(url, params=params)
|
|
152
|
+
except WebexError as e:
|
|
153
|
+
handle_rest_error(e)
|
|
154
|
+
if output == "json":
|
|
155
|
+
print_json(result)
|
|
156
|
+
else:
|
|
157
|
+
if isinstance(result, dict):
|
|
158
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
159
|
+
elif isinstance(result, list):
|
|
160
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
161
|
+
else:
|
|
162
|
+
print_json(result)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@app.command("update-audio")
|
|
167
|
+
def update_audio(
|
|
168
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
169
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. For individual use, if `site"),
|
|
170
|
+
default_audio_type: str = typer.Option(None, "--default-audio-type", help="Choices: webexAudio, voipOnly, otherTeleconferenceService, none"),
|
|
171
|
+
other_teleconference_description: str = typer.Option(None, "--other-teleconference-description", help="Phone number and other information for the teleconference pr"),
|
|
172
|
+
enabled_global_call_in: bool = typer.Option(None, "--enabled-global-call-in/--no-enabled-global-call-in", help="Flag to enable/disable global call ins. ***Note***: If the s"),
|
|
173
|
+
enabled_toll_free: bool = typer.Option(None, "--enabled-toll-free/--no-enabled-toll-free", help="Flag to enable/disable call-ins from toll-free numbers. ***"),
|
|
174
|
+
enabled_auto_connection: bool = typer.Option(None, "--enabled-auto-connection/--no-enabled-auto-connection", help="Flag to enable/disable automatically connecting to audio usi"),
|
|
175
|
+
audio_pin: str = typer.Option(None, "--audio-pin", help="PIN to provide a secondary level of authentication for calls"),
|
|
176
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
177
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
178
|
+
):
|
|
179
|
+
"""Update Audio Options\n\nExample --json-body:\n '{"defaultAudioType":"webexAudio","otherTeleconferenceDescription":"...","enabledGlobalCallIn":true,"enabledTollFree":true,"enabledAutoConnection":true,"officeNumber":{"countryCode":"...","number":"...","enabledCallInAuthentication":true,"enabledCallMe":true},"mobileNumber":{"countryCode":"...","number":"...","enabledCallInAuthentication":true,"enabledCallMe":true},"audioPin":"..."}'."""
|
|
180
|
+
api = get_api(debug=debug)
|
|
181
|
+
url = f"https://webexapis.com/v1/meetingPreferences/audio"
|
|
182
|
+
params = {}
|
|
183
|
+
if user_email is not None:
|
|
184
|
+
params["userEmail"] = user_email
|
|
185
|
+
if site_url is not None:
|
|
186
|
+
params["siteUrl"] = site_url
|
|
187
|
+
if json_body:
|
|
188
|
+
body = json.loads(json_body)
|
|
189
|
+
else:
|
|
190
|
+
body = {}
|
|
191
|
+
if default_audio_type is not None:
|
|
192
|
+
body["defaultAudioType"] = default_audio_type
|
|
193
|
+
if other_teleconference_description is not None:
|
|
194
|
+
body["otherTeleconferenceDescription"] = other_teleconference_description
|
|
195
|
+
if enabled_global_call_in is not None:
|
|
196
|
+
body["enabledGlobalCallIn"] = enabled_global_call_in
|
|
197
|
+
if enabled_toll_free is not None:
|
|
198
|
+
body["enabledTollFree"] = enabled_toll_free
|
|
199
|
+
if enabled_auto_connection is not None:
|
|
200
|
+
body["enabledAutoConnection"] = enabled_auto_connection
|
|
201
|
+
if audio_pin is not None:
|
|
202
|
+
body["audioPin"] = audio_pin
|
|
203
|
+
try:
|
|
204
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
205
|
+
except WebexError as e:
|
|
206
|
+
handle_rest_error(e)
|
|
207
|
+
typer.echo(f"Updated.")
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@app.command("list-video")
|
|
212
|
+
def list_video(
|
|
213
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
214
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. For individual use, if `site"),
|
|
215
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
216
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
217
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
218
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
219
|
+
):
|
|
220
|
+
"""Get Video Options."""
|
|
221
|
+
api = get_api(debug=debug)
|
|
222
|
+
url = f"https://webexapis.com/v1/meetingPreferences/video"
|
|
223
|
+
params = {}
|
|
224
|
+
if user_email is not None:
|
|
225
|
+
params["userEmail"] = user_email
|
|
226
|
+
if site_url is not None:
|
|
227
|
+
params["siteUrl"] = site_url
|
|
228
|
+
if limit > 0:
|
|
229
|
+
params["max"] = limit
|
|
230
|
+
if offset > 0:
|
|
231
|
+
params["start"] = offset
|
|
232
|
+
result = None
|
|
233
|
+
try:
|
|
234
|
+
result = api.session.rest_get(url, params=params)
|
|
235
|
+
except WebexError as e:
|
|
236
|
+
handle_rest_error(e)
|
|
237
|
+
result = result or []
|
|
238
|
+
items = result.get("videoDevices", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
239
|
+
if output == "json":
|
|
240
|
+
print_json(items)
|
|
241
|
+
else:
|
|
242
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
@app.command("update-video")
|
|
247
|
+
def update_video(
|
|
248
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
249
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. For individual use, if `site"),
|
|
250
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
251
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
252
|
+
):
|
|
253
|
+
"""Update Video Options\n\nExample --json-body:\n '{"videoDevices":[{"deviceName":"...","deviceAddress":"...","isDefault":"..."}]}'."""
|
|
254
|
+
api = get_api(debug=debug)
|
|
255
|
+
url = f"https://webexapis.com/v1/meetingPreferences/video"
|
|
256
|
+
params = {}
|
|
257
|
+
if user_email is not None:
|
|
258
|
+
params["userEmail"] = user_email
|
|
259
|
+
if site_url is not None:
|
|
260
|
+
params["siteUrl"] = site_url
|
|
261
|
+
if json_body:
|
|
262
|
+
body = json.loads(json_body)
|
|
263
|
+
else:
|
|
264
|
+
body = {}
|
|
265
|
+
try:
|
|
266
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
267
|
+
except WebexError as e:
|
|
268
|
+
handle_rest_error(e)
|
|
269
|
+
typer.echo(f"Updated.")
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
@app.command("list-scheduling-options")
|
|
274
|
+
def list_scheduling_options(
|
|
275
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
276
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. For individual use, if `site"),
|
|
277
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
278
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
279
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
280
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
281
|
+
):
|
|
282
|
+
"""Get Scheduling Options."""
|
|
283
|
+
api = get_api(debug=debug)
|
|
284
|
+
url = f"https://webexapis.com/v1/meetingPreferences/schedulingOptions"
|
|
285
|
+
params = {}
|
|
286
|
+
if user_email is not None:
|
|
287
|
+
params["userEmail"] = user_email
|
|
288
|
+
if site_url is not None:
|
|
289
|
+
params["siteUrl"] = site_url
|
|
290
|
+
if limit > 0:
|
|
291
|
+
params["max"] = limit
|
|
292
|
+
if offset > 0:
|
|
293
|
+
params["start"] = offset
|
|
294
|
+
result = None
|
|
295
|
+
try:
|
|
296
|
+
result = api.session.rest_get(url, params=params)
|
|
297
|
+
except WebexError as e:
|
|
298
|
+
handle_rest_error(e)
|
|
299
|
+
result = result or []
|
|
300
|
+
items = result.get("delegateEmails", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
301
|
+
if output == "json":
|
|
302
|
+
print_json(items)
|
|
303
|
+
else:
|
|
304
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
@app.command("update-scheduling-options")
|
|
309
|
+
def update_scheduling_options(
|
|
310
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
311
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. For individual use, if `site"),
|
|
312
|
+
enabled_join_before_host: bool = typer.Option(None, "--enabled-join-before-host/--no-enabled-join-before-host", help="Flag to enable/disable ***Join Before Host***. The period du"),
|
|
313
|
+
join_before_host_minutes: str = typer.Option(None, "--join-before-host-minutes", help="Number of minutes before the start time that an invitee can"),
|
|
314
|
+
enabled_auto_share_recording: bool = typer.Option(None, "--enabled-auto-share-recording/--no-enabled-auto-share-recording", help="Flag to enable/disable the automatic sharing of the meeting"),
|
|
315
|
+
enabled_webex_assistant_by_default: bool = typer.Option(None, "--enabled-webex-assistant-by-default/--no-enabled-webex-assistant-by-default", help="Flag to automatically enable Webex Assistant whenever you st"),
|
|
316
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
317
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
318
|
+
):
|
|
319
|
+
"""Update Scheduling Options\n\nExample --json-body:\n '{"enabledJoinBeforeHost":true,"joinBeforeHostMinutes":0,"enabledAutoShareRecording":true,"enabledWebexAssistantByDefault":true,"delegateEmails":["..."]}'."""
|
|
320
|
+
api = get_api(debug=debug)
|
|
321
|
+
url = f"https://webexapis.com/v1/meetingPreferences/schedulingOptions"
|
|
322
|
+
params = {}
|
|
323
|
+
if user_email is not None:
|
|
324
|
+
params["userEmail"] = user_email
|
|
325
|
+
if site_url is not None:
|
|
326
|
+
params["siteUrl"] = site_url
|
|
327
|
+
if json_body:
|
|
328
|
+
body = json.loads(json_body)
|
|
329
|
+
else:
|
|
330
|
+
body = {}
|
|
331
|
+
if enabled_join_before_host is not None:
|
|
332
|
+
body["enabledJoinBeforeHost"] = enabled_join_before_host
|
|
333
|
+
if join_before_host_minutes is not None:
|
|
334
|
+
body["joinBeforeHostMinutes"] = join_before_host_minutes
|
|
335
|
+
if enabled_auto_share_recording is not None:
|
|
336
|
+
body["enabledAutoShareRecording"] = enabled_auto_share_recording
|
|
337
|
+
if enabled_webex_assistant_by_default is not None:
|
|
338
|
+
body["enabledWebexAssistantByDefault"] = enabled_webex_assistant_by_default
|
|
339
|
+
try:
|
|
340
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
341
|
+
except WebexError as e:
|
|
342
|
+
handle_rest_error(e)
|
|
343
|
+
typer.echo(f"Updated.")
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
@app.command("create")
|
|
348
|
+
def create(
|
|
349
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
350
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. For individual use, if `site"),
|
|
351
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
352
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
353
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
354
|
+
):
|
|
355
|
+
"""Insert Delegate Emails\n\nExample --json-body:\n '{"emails":["..."]}'."""
|
|
356
|
+
api = get_api(debug=debug)
|
|
357
|
+
url = f"https://webexapis.com/v1/meetingPreferences/schedulingOptions/delegateEmails/insert"
|
|
358
|
+
params = {}
|
|
359
|
+
if user_email is not None:
|
|
360
|
+
params["userEmail"] = user_email
|
|
361
|
+
if site_url is not None:
|
|
362
|
+
params["siteUrl"] = site_url
|
|
363
|
+
if json_body:
|
|
364
|
+
body = json.loads(json_body)
|
|
365
|
+
else:
|
|
366
|
+
body = {}
|
|
367
|
+
try:
|
|
368
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
369
|
+
except WebexError as e:
|
|
370
|
+
handle_rest_error(e)
|
|
371
|
+
if output == "json":
|
|
372
|
+
print_json(result)
|
|
373
|
+
elif isinstance(result, dict) and "id" in result:
|
|
374
|
+
typer.echo(f"Created: {result['id']}")
|
|
375
|
+
elif not result or result == {}:
|
|
376
|
+
typer.echo("Created.")
|
|
377
|
+
else:
|
|
378
|
+
print_json(result)
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
@app.command("create-delete")
|
|
383
|
+
def create_delete(
|
|
384
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
385
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. For individual use, if `site"),
|
|
386
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
387
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
388
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
389
|
+
):
|
|
390
|
+
"""Delete Delegate Emails\n\nExample --json-body:\n '{"emails":["..."]}'."""
|
|
391
|
+
api = get_api(debug=debug)
|
|
392
|
+
url = f"https://webexapis.com/v1/meetingPreferences/schedulingOptions/delegateEmails/delete"
|
|
393
|
+
params = {}
|
|
394
|
+
if user_email is not None:
|
|
395
|
+
params["userEmail"] = user_email
|
|
396
|
+
if site_url is not None:
|
|
397
|
+
params["siteUrl"] = site_url
|
|
398
|
+
if json_body:
|
|
399
|
+
body = json.loads(json_body)
|
|
400
|
+
else:
|
|
401
|
+
body = {}
|
|
402
|
+
try:
|
|
403
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
404
|
+
except WebexError as e:
|
|
405
|
+
handle_rest_error(e)
|
|
406
|
+
if output == "json":
|
|
407
|
+
print_json(result)
|
|
408
|
+
elif isinstance(result, dict) and "id" in result:
|
|
409
|
+
typer.echo(f"Created: {result['id']}")
|
|
410
|
+
elif not result or result == {}:
|
|
411
|
+
typer.echo("Created.")
|
|
412
|
+
else:
|
|
413
|
+
print_json(result)
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
@app.command("list-sites")
|
|
418
|
+
def list_sites(
|
|
419
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
420
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. If `siteUrl` is not specifie"),
|
|
421
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
422
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
423
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
424
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
425
|
+
):
|
|
426
|
+
"""Get Site List."""
|
|
427
|
+
api = get_api(debug=debug)
|
|
428
|
+
url = f"https://webexapis.com/v1/meetingPreferences/sites"
|
|
429
|
+
params = {}
|
|
430
|
+
if user_email is not None:
|
|
431
|
+
params["userEmail"] = user_email
|
|
432
|
+
if site_url is not None:
|
|
433
|
+
params["siteUrl"] = site_url
|
|
434
|
+
if limit > 0:
|
|
435
|
+
params["max"] = limit
|
|
436
|
+
if offset > 0:
|
|
437
|
+
params["start"] = offset
|
|
438
|
+
result = None
|
|
439
|
+
try:
|
|
440
|
+
result = api.session.rest_get(url, params=params)
|
|
441
|
+
except WebexError as e:
|
|
442
|
+
handle_rest_error(e)
|
|
443
|
+
result = result or []
|
|
444
|
+
items = result.get("sites", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
445
|
+
if output == "json":
|
|
446
|
+
print_json(items)
|
|
447
|
+
else:
|
|
448
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
@app.command("update-sites")
|
|
453
|
+
def update_sites(
|
|
454
|
+
default_site: str = typer.Option(..., "--default-site", help="Whether or not to change user's default site. ***Note***: `d"),
|
|
455
|
+
user_email: str = typer.Option(None, "--user-email", help="Email address for the user. This parameter is only used if t"),
|
|
456
|
+
site_url: str = typer.Option(None, "--site-url", help="Access URL for the site."),
|
|
457
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
458
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
459
|
+
):
|
|
460
|
+
"""Update Default Site."""
|
|
461
|
+
api = get_api(debug=debug)
|
|
462
|
+
url = f"https://webexapis.com/v1/meetingPreferences/sites"
|
|
463
|
+
params = {}
|
|
464
|
+
if default_site is not None:
|
|
465
|
+
params["defaultSite"] = default_site
|
|
466
|
+
if user_email is not None:
|
|
467
|
+
params["userEmail"] = user_email
|
|
468
|
+
if json_body:
|
|
469
|
+
body = json.loads(json_body)
|
|
470
|
+
else:
|
|
471
|
+
body = {}
|
|
472
|
+
if site_url is not None:
|
|
473
|
+
body["siteUrl"] = site_url
|
|
474
|
+
try:
|
|
475
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
476
|
+
except WebexError as e:
|
|
477
|
+
handle_rest_error(e)
|
|
478
|
+
typer.echo(f"Updated.")
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
@app.command("create-refresh-id")
|
|
483
|
+
def create_refresh_id(
|
|
484
|
+
site_url: str = typer.Option(None, "--site-url", help="(required) Site URL to refresh the personal room IDs."),
|
|
485
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
486
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
487
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
488
|
+
):
|
|
489
|
+
"""Batch Refresh Personal Meeting Room ID\n\nExample --json-body:\n '{"siteUrl":"...","personalMeetingRoomIds":[{"email":"...","personId":"...","systemGenerated":"...","personalMeetingRoomId":"..."}]}'."""
|
|
490
|
+
api = get_api(debug=debug)
|
|
491
|
+
url = f"https://webexapis.com/v1/admin/meetingPreferences/personalMeetingRoom/refreshId"
|
|
492
|
+
if json_body:
|
|
493
|
+
body = json.loads(json_body)
|
|
494
|
+
else:
|
|
495
|
+
body = {}
|
|
496
|
+
if site_url is not None:
|
|
497
|
+
body["siteUrl"] = site_url
|
|
498
|
+
_missing = [f for f in ['siteUrl'] if f not in body or body[f] is None]
|
|
499
|
+
if _missing:
|
|
500
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
501
|
+
raise typer.Exit(1)
|
|
502
|
+
try:
|
|
503
|
+
result = api.session.rest_post(url, json=body)
|
|
504
|
+
except WebexError as e:
|
|
505
|
+
handle_rest_error(e)
|
|
506
|
+
if output == "json":
|
|
507
|
+
print_json(result)
|
|
508
|
+
elif isinstance(result, dict) and "id" in result:
|
|
509
|
+
typer.echo(f"Created: {result['id']}")
|
|
510
|
+
elif not result or result == {}:
|
|
511
|
+
typer.echo("Created.")
|
|
512
|
+
else:
|
|
513
|
+
print_json(result)
|
|
514
|
+
|
|
515
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typer
|
|
3
|
+
from wxcli.auth import get_api
|
|
4
|
+
from wxcli.errors import WebexError, handle_rest_error
|
|
5
|
+
from wxcli.output import print_table, print_json
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
app = typer.Typer(help="Manage Webex Meetings meeting-qa.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("list")
|
|
12
|
+
def cmd_list(
|
|
13
|
+
meeting_id: str = typer.Option(..., "--meeting-id", help="A unique identifier for the [meeting instance](/docs/meeting"),
|
|
14
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
15
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
16
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
17
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
18
|
+
):
|
|
19
|
+
"""List Meeting Q and A."""
|
|
20
|
+
api = get_api(debug=debug)
|
|
21
|
+
url = f"https://webexapis.com/v1/meetings/q_and_a"
|
|
22
|
+
params = {}
|
|
23
|
+
if meeting_id is not None:
|
|
24
|
+
params["meetingId"] = meeting_id
|
|
25
|
+
if limit > 0:
|
|
26
|
+
params["max"] = limit
|
|
27
|
+
if offset > 0:
|
|
28
|
+
params["start"] = offset
|
|
29
|
+
try:
|
|
30
|
+
if limit > 0:
|
|
31
|
+
result = api.session.rest_get(url, params=params)
|
|
32
|
+
result = result or {}
|
|
33
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
34
|
+
else:
|
|
35
|
+
items = list(api.session.follow_pagination(url=url, params=params, item_key="items"))
|
|
36
|
+
except WebexError as e:
|
|
37
|
+
handle_rest_error(e)
|
|
38
|
+
if output == "json":
|
|
39
|
+
print_json(items)
|
|
40
|
+
else:
|
|
41
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@app.command("list-answers")
|
|
46
|
+
def list_answers(
|
|
47
|
+
question_id: str = typer.Argument(help="questionId"),
|
|
48
|
+
meeting_id: str = typer.Option(..., "--meeting-id", help="A unique identifier for the [meeting instance](/docs/meeting"),
|
|
49
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
50
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
51
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
52
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
53
|
+
):
|
|
54
|
+
"""List Answers of a Question."""
|
|
55
|
+
api = get_api(debug=debug)
|
|
56
|
+
url = f"https://webexapis.com/v1/meetings/q_and_a/{question_id}/answers"
|
|
57
|
+
params = {}
|
|
58
|
+
if meeting_id is not None:
|
|
59
|
+
params["meetingId"] = meeting_id
|
|
60
|
+
if limit > 0:
|
|
61
|
+
params["max"] = limit
|
|
62
|
+
if offset > 0:
|
|
63
|
+
params["start"] = offset
|
|
64
|
+
try:
|
|
65
|
+
if limit > 0:
|
|
66
|
+
result = api.session.rest_get(url, params=params)
|
|
67
|
+
result = result or {}
|
|
68
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
69
|
+
else:
|
|
70
|
+
items = list(api.session.follow_pagination(url=url, params=params, item_key="items"))
|
|
71
|
+
except WebexError as e:
|
|
72
|
+
handle_rest_error(e)
|
|
73
|
+
if output == "json":
|
|
74
|
+
print_json(items)
|
|
75
|
+
else:
|
|
76
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
77
|
+
|
|
78
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typer
|
|
3
|
+
from wxcli.auth import get_api
|
|
4
|
+
from wxcli.errors import WebexError, handle_rest_error
|
|
5
|
+
from wxcli.output import print_table, print_json
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
app = typer.Typer(help="Manage Webex Meetings meeting-qualities.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("list")
|
|
12
|
+
def cmd_list(
|
|
13
|
+
meeting_id: str = typer.Option(..., "--meeting-id", help="Unique identifier for the specific meeting instance. **Note:"),
|
|
14
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
15
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
16
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
17
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
18
|
+
):
|
|
19
|
+
"""Get Meeting Qualities."""
|
|
20
|
+
api = get_api(debug=debug)
|
|
21
|
+
url = f"https://webexapis.com/v1/meeting/qualities"
|
|
22
|
+
params = {}
|
|
23
|
+
if meeting_id is not None:
|
|
24
|
+
params["meetingId"] = meeting_id
|
|
25
|
+
if limit > 0:
|
|
26
|
+
params["max"] = limit
|
|
27
|
+
if offset > 0:
|
|
28
|
+
params["offset"] = offset
|
|
29
|
+
try:
|
|
30
|
+
if limit > 0:
|
|
31
|
+
result = api.session.rest_get(url, params=params)
|
|
32
|
+
result = result or {}
|
|
33
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
34
|
+
else:
|
|
35
|
+
items = list(api.session.follow_pagination(url=url, params=params, item_key="items"))
|
|
36
|
+
except WebexError as e:
|
|
37
|
+
handle_rest_error(e)
|
|
38
|
+
if output == "json":
|
|
39
|
+
print_json(items)
|
|
40
|
+
else:
|
|
41
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
42
|
+
|
|
43
|
+
|