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,494 @@
|
|
|
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
|
+
from wxcli.config import get_org_id
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
app = typer.Typer(help="Manage Webex Calling call-park.")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.command("list")
|
|
13
|
+
def cmd_list(
|
|
14
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
15
|
+
order: str = typer.Option(None, "--order", help="Sort the list of call parks by name, either ASC or DSC. Defa"),
|
|
16
|
+
name: str = typer.Option(None, "--name", help="Return the list of call parks that contains the given name."),
|
|
17
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
18
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
19
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
20
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
21
|
+
):
|
|
22
|
+
"""Read the List of Call Parks."""
|
|
23
|
+
api = get_api(debug=debug)
|
|
24
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParks"
|
|
25
|
+
params = {}
|
|
26
|
+
if order is not None:
|
|
27
|
+
params["order"] = order
|
|
28
|
+
if name is not None:
|
|
29
|
+
params["name"] = name
|
|
30
|
+
if limit > 0:
|
|
31
|
+
params["max"] = limit
|
|
32
|
+
if offset > 0:
|
|
33
|
+
params["start"] = offset
|
|
34
|
+
org_id = get_org_id()
|
|
35
|
+
if org_id is not None:
|
|
36
|
+
params["orgId"] = org_id
|
|
37
|
+
result = None
|
|
38
|
+
try:
|
|
39
|
+
result = api.session.rest_get(url, params=params)
|
|
40
|
+
except WebexError as e:
|
|
41
|
+
handle_rest_error(e)
|
|
42
|
+
result = result or []
|
|
43
|
+
items = result.get("callParks", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
44
|
+
if output == "json":
|
|
45
|
+
print_json(items)
|
|
46
|
+
else:
|
|
47
|
+
print_table(items, columns=[('ID', 'id'), ('Name', 'name')], limit=limit)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@app.command("create")
|
|
52
|
+
def create(
|
|
53
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
54
|
+
name: str = typer.Option(None, "--name", help="(required) Unique name for the call park. The maximum length is 80."),
|
|
55
|
+
park_on_agents_enabled: bool = typer.Option(None, "--park-on-agents-enabled/--no-park-on-agents-enabled", help="Whether or not the calls will be parked on agents as a desti"),
|
|
56
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
57
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
58
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
59
|
+
):
|
|
60
|
+
"""Create a Call Park\n\nExample --json-body:\n '{"name":"...","recall":{"option":"ALERT_PARKING_USER_ONLY","huntGroupId":"..."},"agents":["..."],"parkOnAgentsEnabled":true,"callParkExtensions":["..."]}'."""
|
|
61
|
+
api = get_api(debug=debug)
|
|
62
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParks"
|
|
63
|
+
params = {}
|
|
64
|
+
org_id = get_org_id()
|
|
65
|
+
if org_id is not None:
|
|
66
|
+
params["orgId"] = org_id
|
|
67
|
+
if json_body:
|
|
68
|
+
body = json.loads(json_body)
|
|
69
|
+
else:
|
|
70
|
+
body = {}
|
|
71
|
+
if name is not None:
|
|
72
|
+
body["name"] = name
|
|
73
|
+
if park_on_agents_enabled is not None:
|
|
74
|
+
body["parkOnAgentsEnabled"] = park_on_agents_enabled
|
|
75
|
+
_missing = [f for f in ['name'] if f not in body or body[f] is None]
|
|
76
|
+
if _missing:
|
|
77
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
78
|
+
raise typer.Exit(1)
|
|
79
|
+
try:
|
|
80
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
81
|
+
except WebexError as e:
|
|
82
|
+
handle_rest_error(e)
|
|
83
|
+
if output == "json":
|
|
84
|
+
print_json(result)
|
|
85
|
+
elif isinstance(result, dict) and "id" in result:
|
|
86
|
+
typer.echo(f"Created: {result['id']}")
|
|
87
|
+
elif not result or result == {}:
|
|
88
|
+
typer.echo("Created.")
|
|
89
|
+
else:
|
|
90
|
+
print_json(result)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@app.command("show")
|
|
95
|
+
def show(
|
|
96
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
97
|
+
call_park_id: str = typer.Argument(help="callParkId"),
|
|
98
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
99
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
100
|
+
):
|
|
101
|
+
"""Get Details for a Call Park."""
|
|
102
|
+
api = get_api(debug=debug)
|
|
103
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParks/{call_park_id}"
|
|
104
|
+
params = {}
|
|
105
|
+
org_id = get_org_id()
|
|
106
|
+
if org_id is not None:
|
|
107
|
+
params["orgId"] = org_id
|
|
108
|
+
try:
|
|
109
|
+
result = api.session.rest_get(url, params=params)
|
|
110
|
+
except WebexError as e:
|
|
111
|
+
handle_rest_error(e)
|
|
112
|
+
if output == "json":
|
|
113
|
+
print_json(result)
|
|
114
|
+
else:
|
|
115
|
+
if isinstance(result, dict):
|
|
116
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
117
|
+
elif isinstance(result, list):
|
|
118
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
119
|
+
else:
|
|
120
|
+
print_json(result)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@app.command("update")
|
|
125
|
+
def update(
|
|
126
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
127
|
+
call_park_id: str = typer.Argument(help="callParkId"),
|
|
128
|
+
name: str = typer.Option(None, "--name", help="Unique name for the call park. The maximum length is 80."),
|
|
129
|
+
park_on_agents_enabled: bool = typer.Option(None, "--park-on-agents-enabled/--no-park-on-agents-enabled", help="Whether or not the calls will be parked on agents as a desti"),
|
|
130
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
131
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
132
|
+
):
|
|
133
|
+
"""Update a Call Park\n\nExample --json-body:\n '{"name":"...","recall":{"option":"ALERT_PARKING_USER_ONLY","huntGroupId":"..."},"agents":["..."],"parkOnAgentsEnabled":true,"callParkExtensions":["..."]}'."""
|
|
134
|
+
api = get_api(debug=debug)
|
|
135
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParks/{call_park_id}"
|
|
136
|
+
params = {}
|
|
137
|
+
org_id = get_org_id()
|
|
138
|
+
if org_id is not None:
|
|
139
|
+
params["orgId"] = org_id
|
|
140
|
+
if json_body:
|
|
141
|
+
body = json.loads(json_body)
|
|
142
|
+
else:
|
|
143
|
+
body = {}
|
|
144
|
+
if name is not None:
|
|
145
|
+
body["name"] = name
|
|
146
|
+
if park_on_agents_enabled is not None:
|
|
147
|
+
body["parkOnAgentsEnabled"] = park_on_agents_enabled
|
|
148
|
+
try:
|
|
149
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
150
|
+
except WebexError as e:
|
|
151
|
+
handle_rest_error(e)
|
|
152
|
+
typer.echo(f"Updated.")
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@app.command("delete")
|
|
157
|
+
def delete(
|
|
158
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
159
|
+
call_park_id: str = typer.Argument(help="callParkId"),
|
|
160
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
161
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
162
|
+
):
|
|
163
|
+
"""Delete a Call Park."""
|
|
164
|
+
if not force:
|
|
165
|
+
typer.confirm(f"Delete {call_park_id}?", abort=True)
|
|
166
|
+
api = get_api(debug=debug)
|
|
167
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParks/{call_park_id}"
|
|
168
|
+
params = {}
|
|
169
|
+
org_id = get_org_id()
|
|
170
|
+
if org_id is not None:
|
|
171
|
+
params["orgId"] = org_id
|
|
172
|
+
try:
|
|
173
|
+
api.session.rest_delete(url, params=params)
|
|
174
|
+
except WebexError as e:
|
|
175
|
+
handle_rest_error(e)
|
|
176
|
+
typer.echo(f"Deleted: {call_park_id}")
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
@app.command("list-available-users")
|
|
181
|
+
def list_available_users(
|
|
182
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
183
|
+
call_park_name: str = typer.Option(None, "--call-park-name", help="Only return available agents from call parks with the matchi"),
|
|
184
|
+
name: str = typer.Option(None, "--name", help="Only return available agents with the matching name."),
|
|
185
|
+
phone_number: str = typer.Option(None, "--phone-number", help="Only return available agents with the matching primary numbe"),
|
|
186
|
+
order: str = typer.Option(None, "--order", help="Order the available agents according to the designated field"),
|
|
187
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
188
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
189
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
190
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
191
|
+
):
|
|
192
|
+
"""Get available agents from Call Parks."""
|
|
193
|
+
api = get_api(debug=debug)
|
|
194
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParks/availableUsers"
|
|
195
|
+
params = {}
|
|
196
|
+
if call_park_name is not None:
|
|
197
|
+
params["callParkName"] = call_park_name
|
|
198
|
+
if name is not None:
|
|
199
|
+
params["name"] = name
|
|
200
|
+
if phone_number is not None:
|
|
201
|
+
params["phoneNumber"] = phone_number
|
|
202
|
+
if order is not None:
|
|
203
|
+
params["order"] = order
|
|
204
|
+
if limit > 0:
|
|
205
|
+
params["max"] = limit
|
|
206
|
+
if offset > 0:
|
|
207
|
+
params["start"] = offset
|
|
208
|
+
org_id = get_org_id()
|
|
209
|
+
if org_id is not None:
|
|
210
|
+
params["orgId"] = org_id
|
|
211
|
+
result = None
|
|
212
|
+
try:
|
|
213
|
+
result = api.session.rest_get(url, params=params)
|
|
214
|
+
except WebexError as e:
|
|
215
|
+
handle_rest_error(e)
|
|
216
|
+
result = result or []
|
|
217
|
+
items = result.get("agents", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
218
|
+
if output == "json":
|
|
219
|
+
print_json(items)
|
|
220
|
+
else:
|
|
221
|
+
print_table(items, columns=[('ID', 'id'), ('Name', 'name')], limit=limit)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@app.command("list-available-recall-hunt-groups")
|
|
226
|
+
def list_available_recall_hunt_groups(
|
|
227
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
228
|
+
name: str = typer.Option(None, "--name", help="Only return available recall hunt groups with the matching n"),
|
|
229
|
+
order: str = typer.Option(None, "--order", help="Order the available recall hunt groups according to the desi"),
|
|
230
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
231
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
232
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
233
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
234
|
+
):
|
|
235
|
+
"""Get available recall hunt groups from Call Parks."""
|
|
236
|
+
api = get_api(debug=debug)
|
|
237
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParks/availableRecallHuntGroups"
|
|
238
|
+
params = {}
|
|
239
|
+
if name is not None:
|
|
240
|
+
params["name"] = name
|
|
241
|
+
if order is not None:
|
|
242
|
+
params["order"] = order
|
|
243
|
+
if limit > 0:
|
|
244
|
+
params["max"] = limit
|
|
245
|
+
if offset > 0:
|
|
246
|
+
params["start"] = offset
|
|
247
|
+
org_id = get_org_id()
|
|
248
|
+
if org_id is not None:
|
|
249
|
+
params["orgId"] = org_id
|
|
250
|
+
result = None
|
|
251
|
+
try:
|
|
252
|
+
result = api.session.rest_get(url, params=params)
|
|
253
|
+
except WebexError as e:
|
|
254
|
+
handle_rest_error(e)
|
|
255
|
+
result = result or []
|
|
256
|
+
items = result.get("huntGroups", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
257
|
+
if output == "json":
|
|
258
|
+
print_json(items)
|
|
259
|
+
else:
|
|
260
|
+
print_table(items, columns=[('ID', 'id'), ('Name', 'name')], limit=limit)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
@app.command("show-settings")
|
|
265
|
+
def show_settings(
|
|
266
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
267
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
268
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
269
|
+
):
|
|
270
|
+
"""Get Call Park Settings."""
|
|
271
|
+
api = get_api(debug=debug)
|
|
272
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParks/settings"
|
|
273
|
+
params = {}
|
|
274
|
+
org_id = get_org_id()
|
|
275
|
+
if org_id is not None:
|
|
276
|
+
params["orgId"] = org_id
|
|
277
|
+
try:
|
|
278
|
+
result = api.session.rest_get(url, params=params)
|
|
279
|
+
except WebexError as e:
|
|
280
|
+
handle_rest_error(e)
|
|
281
|
+
if output == "json":
|
|
282
|
+
print_json(result)
|
|
283
|
+
else:
|
|
284
|
+
if isinstance(result, dict):
|
|
285
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
286
|
+
elif isinstance(result, list):
|
|
287
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
288
|
+
else:
|
|
289
|
+
print_json(result)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@app.command("update-settings")
|
|
294
|
+
def update_settings(
|
|
295
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
296
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
297
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
298
|
+
):
|
|
299
|
+
"""Update Call Park settings\n\nExample --json-body:\n '{"callParkRecall":{"option":"ALERT_PARKING_USER_ONLY","huntGroupId":"..."},"callParkSettings":{"ringPattern":"NORMAL","recallTime":0,"huntWaitTime":0}}'."""
|
|
300
|
+
api = get_api(debug=debug)
|
|
301
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParks/settings"
|
|
302
|
+
params = {}
|
|
303
|
+
org_id = get_org_id()
|
|
304
|
+
if org_id is not None:
|
|
305
|
+
params["orgId"] = org_id
|
|
306
|
+
if json_body:
|
|
307
|
+
body = json.loads(json_body)
|
|
308
|
+
else:
|
|
309
|
+
body = {}
|
|
310
|
+
try:
|
|
311
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
312
|
+
except WebexError as e:
|
|
313
|
+
handle_rest_error(e)
|
|
314
|
+
typer.echo(f"Updated.")
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
@app.command("list-call-park-extensions")
|
|
319
|
+
def list_call_park_extensions(
|
|
320
|
+
location_id: str = typer.Option(None, "--location-id", help="Only return call park extensions with matching location ID."),
|
|
321
|
+
extension: str = typer.Option(None, "--extension", help="Only return call park extensions with the matching extension"),
|
|
322
|
+
location_name: str = typer.Option(None, "--location-name", help="Only return call park extensions with the matching extension"),
|
|
323
|
+
name: str = typer.Option(None, "--name", help="Only return call park extensions with the matching name."),
|
|
324
|
+
order: str = typer.Option(None, "--order", help="Order the available agents according to the designated field"),
|
|
325
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
326
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
327
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
328
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
329
|
+
):
|
|
330
|
+
"""Read the List of Call Park Extensions."""
|
|
331
|
+
api = get_api(debug=debug)
|
|
332
|
+
url = f"https://webexapis.com/v1/telephony/config/callParkExtensions"
|
|
333
|
+
params = {}
|
|
334
|
+
if location_id is not None:
|
|
335
|
+
params["locationId"] = location_id
|
|
336
|
+
if extension is not None:
|
|
337
|
+
params["extension"] = extension
|
|
338
|
+
if location_name is not None:
|
|
339
|
+
params["locationName"] = location_name
|
|
340
|
+
if name is not None:
|
|
341
|
+
params["name"] = name
|
|
342
|
+
if order is not None:
|
|
343
|
+
params["order"] = order
|
|
344
|
+
if limit > 0:
|
|
345
|
+
params["max"] = limit
|
|
346
|
+
if offset > 0:
|
|
347
|
+
params["start"] = offset
|
|
348
|
+
org_id = get_org_id()
|
|
349
|
+
if org_id is not None:
|
|
350
|
+
params["orgId"] = org_id
|
|
351
|
+
try:
|
|
352
|
+
if limit > 0:
|
|
353
|
+
result = api.session.rest_get(url, params=params)
|
|
354
|
+
result = result or {}
|
|
355
|
+
items = result.get("callParkExtensions", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
356
|
+
else:
|
|
357
|
+
items = list(api.session.follow_pagination(url=url, params=params, item_key="callParkExtensions"))
|
|
358
|
+
except WebexError as e:
|
|
359
|
+
handle_rest_error(e)
|
|
360
|
+
if output == "json":
|
|
361
|
+
print_json(items)
|
|
362
|
+
else:
|
|
363
|
+
print_table(items, columns=[('ID', 'id'), ('Name', 'name')], limit=limit)
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
@app.command("show-call-park-extensions")
|
|
368
|
+
def show_call_park_extensions(
|
|
369
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
370
|
+
call_park_extension_id: str = typer.Argument(help="callParkExtensionId"),
|
|
371
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
372
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
373
|
+
):
|
|
374
|
+
"""Get Details for a Call Park Extension."""
|
|
375
|
+
api = get_api(debug=debug)
|
|
376
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParkExtensions/{call_park_extension_id}"
|
|
377
|
+
params = {}
|
|
378
|
+
org_id = get_org_id()
|
|
379
|
+
if org_id is not None:
|
|
380
|
+
params["orgId"] = org_id
|
|
381
|
+
try:
|
|
382
|
+
result = api.session.rest_get(url, params=params)
|
|
383
|
+
except WebexError as e:
|
|
384
|
+
handle_rest_error(e)
|
|
385
|
+
if output == "json":
|
|
386
|
+
print_json(result)
|
|
387
|
+
else:
|
|
388
|
+
if isinstance(result, dict):
|
|
389
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
390
|
+
elif isinstance(result, list):
|
|
391
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
392
|
+
else:
|
|
393
|
+
print_json(result)
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
@app.command("update-call-park-extensions")
|
|
398
|
+
def update_call_park_extensions(
|
|
399
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
400
|
+
call_park_extension_id: str = typer.Argument(help="callParkExtensionId"),
|
|
401
|
+
name: str = typer.Option(None, "--name", help="Name for the call park extension. The maximum length is 30."),
|
|
402
|
+
extension: str = typer.Option(None, "--extension", help="Unique extension which will be assigned to call park extensi"),
|
|
403
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
404
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
405
|
+
):
|
|
406
|
+
"""Update a Call Park Extension."""
|
|
407
|
+
api = get_api(debug=debug)
|
|
408
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParkExtensions/{call_park_extension_id}"
|
|
409
|
+
params = {}
|
|
410
|
+
org_id = get_org_id()
|
|
411
|
+
if org_id is not None:
|
|
412
|
+
params["orgId"] = org_id
|
|
413
|
+
if json_body:
|
|
414
|
+
body = json.loads(json_body)
|
|
415
|
+
else:
|
|
416
|
+
body = {}
|
|
417
|
+
if name is not None:
|
|
418
|
+
body["name"] = name
|
|
419
|
+
if extension is not None:
|
|
420
|
+
body["extension"] = extension
|
|
421
|
+
try:
|
|
422
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
423
|
+
except WebexError as e:
|
|
424
|
+
handle_rest_error(e)
|
|
425
|
+
typer.echo(f"Updated.")
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
@app.command("delete-call-park-extensions")
|
|
430
|
+
def delete_call_park_extensions(
|
|
431
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
432
|
+
call_park_extension_id: str = typer.Argument(help="callParkExtensionId"),
|
|
433
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
434
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
435
|
+
):
|
|
436
|
+
"""Delete a Call Park Extension."""
|
|
437
|
+
if not force:
|
|
438
|
+
typer.confirm(f"Delete {call_park_extension_id}?", abort=True)
|
|
439
|
+
api = get_api(debug=debug)
|
|
440
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParkExtensions/{call_park_extension_id}"
|
|
441
|
+
params = {}
|
|
442
|
+
org_id = get_org_id()
|
|
443
|
+
if org_id is not None:
|
|
444
|
+
params["orgId"] = org_id
|
|
445
|
+
try:
|
|
446
|
+
api.session.rest_delete(url, params=params)
|
|
447
|
+
except WebexError as e:
|
|
448
|
+
handle_rest_error(e)
|
|
449
|
+
typer.echo(f"Deleted: {call_park_extension_id}")
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
@app.command("create-call-park-extensions")
|
|
454
|
+
def create_call_park_extensions(
|
|
455
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
456
|
+
name: str = typer.Option(None, "--name", help="(required) Name for the call park extension. The maximum length is 30."),
|
|
457
|
+
extension: str = typer.Option(None, "--extension", help="(required) Unique extension which will be assigned to call park extensi"),
|
|
458
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
459
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
460
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
461
|
+
):
|
|
462
|
+
"""Create a Call Park Extension."""
|
|
463
|
+
api = get_api(debug=debug)
|
|
464
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callParkExtensions"
|
|
465
|
+
params = {}
|
|
466
|
+
org_id = get_org_id()
|
|
467
|
+
if org_id is not None:
|
|
468
|
+
params["orgId"] = org_id
|
|
469
|
+
if json_body:
|
|
470
|
+
body = json.loads(json_body)
|
|
471
|
+
else:
|
|
472
|
+
body = {}
|
|
473
|
+
if name is not None:
|
|
474
|
+
body["name"] = name
|
|
475
|
+
if extension is not None:
|
|
476
|
+
body["extension"] = extension
|
|
477
|
+
_missing = [f for f in ['name', 'extension'] if f not in body or body[f] is None]
|
|
478
|
+
if _missing:
|
|
479
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
480
|
+
raise typer.Exit(1)
|
|
481
|
+
try:
|
|
482
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
483
|
+
except WebexError as e:
|
|
484
|
+
handle_rest_error(e)
|
|
485
|
+
if output == "json":
|
|
486
|
+
print_json(result)
|
|
487
|
+
elif isinstance(result, dict) and "id" in result:
|
|
488
|
+
typer.echo(f"Created: {result['id']}")
|
|
489
|
+
elif not result or result == {}:
|
|
490
|
+
typer.echo("Created.")
|
|
491
|
+
else:
|
|
492
|
+
print_json(result)
|
|
493
|
+
|
|
494
|
+
|