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,101 @@
|
|
|
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-reports.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("list")
|
|
12
|
+
def cmd_list(
|
|
13
|
+
site_url: str = typer.Option(..., "--site-url", help="URL of the Webex site which the API lists meeting usage repo"),
|
|
14
|
+
service_type: str = typer.Option(None, "--service-type", help="Meeting usage report's service-type. If `serviceType` is spe"),
|
|
15
|
+
from_param: str = typer.Option(None, "--from", help="Starting date and time for meeting usage reports to return,"),
|
|
16
|
+
to: str = typer.Option(None, "--to", help="Ending date and time for meeting usage reports to return, in"),
|
|
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
|
+
"""List Meeting Usage Reports."""
|
|
23
|
+
api = get_api(debug=debug)
|
|
24
|
+
url = f"https://webexapis.com/v1/meetingReports/usage"
|
|
25
|
+
params = {}
|
|
26
|
+
if site_url is not None:
|
|
27
|
+
params["siteUrl"] = site_url
|
|
28
|
+
if service_type is not None:
|
|
29
|
+
params["serviceType"] = service_type
|
|
30
|
+
if from_param is not None:
|
|
31
|
+
params["from"] = from_param
|
|
32
|
+
if to is not None:
|
|
33
|
+
params["to"] = to
|
|
34
|
+
if limit > 0:
|
|
35
|
+
params["max"] = limit
|
|
36
|
+
if offset > 0:
|
|
37
|
+
params["start"] = offset
|
|
38
|
+
try:
|
|
39
|
+
if limit > 0:
|
|
40
|
+
result = api.session.rest_get(url, params=params)
|
|
41
|
+
result = result or {}
|
|
42
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
43
|
+
else:
|
|
44
|
+
items = list(api.session.follow_pagination(url=url, params=params, item_key="items"))
|
|
45
|
+
except WebexError as e:
|
|
46
|
+
handle_rest_error(e)
|
|
47
|
+
if output == "json":
|
|
48
|
+
print_json(items)
|
|
49
|
+
else:
|
|
50
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@app.command("list-attendees")
|
|
55
|
+
def list_attendees(
|
|
56
|
+
site_url: str = typer.Option(..., "--site-url", help="URL of the Webex site which the API lists meeting attendee r"),
|
|
57
|
+
from_param: str = typer.Option(None, "--from", help="Starting date and time for the meeting attendee reports to r"),
|
|
58
|
+
to: str = typer.Option(None, "--to", help="Ending date and time for the meeting attendee reports to ret"),
|
|
59
|
+
meeting_id: str = typer.Option(None, "--meeting-id", help="Meeting ID for the meeting attendee reports to return. If sp"),
|
|
60
|
+
meeting_number: str = typer.Option(None, "--meeting-number", help="Meeting number for the meeting attendee reports to return. I"),
|
|
61
|
+
meeting_title: str = typer.Option(None, "--meeting-title", help="Meeting title for the meeting attendee reports to return. If"),
|
|
62
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
63
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
64
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
65
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
66
|
+
):
|
|
67
|
+
"""List Meeting Attendee Reports."""
|
|
68
|
+
api = get_api(debug=debug)
|
|
69
|
+
url = f"https://webexapis.com/v1/meetingReports/attendees"
|
|
70
|
+
params = {}
|
|
71
|
+
if site_url is not None:
|
|
72
|
+
params["siteUrl"] = site_url
|
|
73
|
+
if from_param is not None:
|
|
74
|
+
params["from"] = from_param
|
|
75
|
+
if to is not None:
|
|
76
|
+
params["to"] = to
|
|
77
|
+
if meeting_id is not None:
|
|
78
|
+
params["meetingId"] = meeting_id
|
|
79
|
+
if meeting_number is not None:
|
|
80
|
+
params["meetingNumber"] = meeting_number
|
|
81
|
+
if meeting_title is not None:
|
|
82
|
+
params["meetingTitle"] = meeting_title
|
|
83
|
+
if limit > 0:
|
|
84
|
+
params["max"] = limit
|
|
85
|
+
if offset > 0:
|
|
86
|
+
params["start"] = offset
|
|
87
|
+
try:
|
|
88
|
+
if limit > 0:
|
|
89
|
+
result = api.session.rest_get(url, params=params)
|
|
90
|
+
result = result or {}
|
|
91
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
92
|
+
else:
|
|
93
|
+
items = list(api.session.follow_pagination(url=url, params=params, item_key="items"))
|
|
94
|
+
except WebexError as e:
|
|
95
|
+
handle_rest_error(e)
|
|
96
|
+
if output == "json":
|
|
97
|
+
print_json(items)
|
|
98
|
+
else:
|
|
99
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
100
|
+
|
|
101
|
+
|
|
@@ -0,0 +1,105 @@
|
|
|
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-session-types.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("list")
|
|
12
|
+
def cmd_list(
|
|
13
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query. If siteUrl is not specified,"),
|
|
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 Site Session Types."""
|
|
20
|
+
api = get_api(debug=debug)
|
|
21
|
+
url = f"https://webexapis.com/v1/admin/meeting/config/sessionTypes"
|
|
22
|
+
params = {}
|
|
23
|
+
if site_url is not None:
|
|
24
|
+
params["siteUrl"] = site_url
|
|
25
|
+
if limit > 0:
|
|
26
|
+
params["max"] = limit
|
|
27
|
+
if offset > 0:
|
|
28
|
+
params["start"] = offset
|
|
29
|
+
result = None
|
|
30
|
+
try:
|
|
31
|
+
result = api.session.rest_get(url, params=params)
|
|
32
|
+
except WebexError as e:
|
|
33
|
+
handle_rest_error(e)
|
|
34
|
+
result = result or []
|
|
35
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
36
|
+
if output == "json":
|
|
37
|
+
print_json(items)
|
|
38
|
+
else:
|
|
39
|
+
print_table(items, columns=[('ID', 'id'), ('Name', 'name'), ('Type', 'type')], limit=limit)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@app.command("list-session-types")
|
|
44
|
+
def list_session_types(
|
|
45
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site to query."),
|
|
46
|
+
person_id: str = typer.Option(None, "--person-id", help="A unique identifier for the user."),
|
|
47
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
48
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
49
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
50
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
51
|
+
):
|
|
52
|
+
"""List User Session Type."""
|
|
53
|
+
api = get_api(debug=debug)
|
|
54
|
+
url = f"https://webexapis.com/v1/admin/meeting/userconfig/sessionTypes"
|
|
55
|
+
params = {}
|
|
56
|
+
if site_url is not None:
|
|
57
|
+
params["siteUrl"] = site_url
|
|
58
|
+
if person_id is not None:
|
|
59
|
+
params["personId"] = person_id
|
|
60
|
+
if limit > 0:
|
|
61
|
+
params["max"] = limit
|
|
62
|
+
if offset > 0:
|
|
63
|
+
params["start"] = offset
|
|
64
|
+
result = None
|
|
65
|
+
try:
|
|
66
|
+
result = api.session.rest_get(url, params=params)
|
|
67
|
+
except WebexError as e:
|
|
68
|
+
handle_rest_error(e)
|
|
69
|
+
result = result or []
|
|
70
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
71
|
+
if output == "json":
|
|
72
|
+
print_json(items)
|
|
73
|
+
else:
|
|
74
|
+
print_table(items, columns=[('ID', 'id'), ('Name', 'name'), ('Type', 'type')], limit=limit)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@app.command("update")
|
|
79
|
+
def update(
|
|
80
|
+
site_url: str = typer.Option(None, "--site-url", help="Site URL for the session type."),
|
|
81
|
+
person_id: str = typer.Option(None, "--person-id", help="A unique identifier for the user."),
|
|
82
|
+
email: str = typer.Option(None, "--email", help="The email of the user."),
|
|
83
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
84
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
85
|
+
):
|
|
86
|
+
"""Update User Session Types\n\nExample --json-body:\n '{"siteUrl":"...","sessionTypeIds":["..."],"personId":"...","email":"..."}'."""
|
|
87
|
+
api = get_api(debug=debug)
|
|
88
|
+
url = f"https://webexapis.com/v1/admin/meeting/userconfig/sessionTypes"
|
|
89
|
+
if json_body:
|
|
90
|
+
body = json.loads(json_body)
|
|
91
|
+
else:
|
|
92
|
+
body = {}
|
|
93
|
+
if site_url is not None:
|
|
94
|
+
body["siteUrl"] = site_url
|
|
95
|
+
if person_id is not None:
|
|
96
|
+
body["personId"] = person_id
|
|
97
|
+
if email is not None:
|
|
98
|
+
body["email"] = email
|
|
99
|
+
try:
|
|
100
|
+
result = api.session.rest_put(url, json=body)
|
|
101
|
+
except WebexError as e:
|
|
102
|
+
handle_rest_error(e)
|
|
103
|
+
typer.echo(f"Updated.")
|
|
104
|
+
|
|
105
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
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-site.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("show")
|
|
12
|
+
def show(
|
|
13
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site which the API queries common settings"),
|
|
14
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
15
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
16
|
+
):
|
|
17
|
+
"""Get Meeting Common Settings Configuration."""
|
|
18
|
+
api = get_api(debug=debug)
|
|
19
|
+
url = f"https://webexapis.com/v1/admin/meeting/config/commonSettings"
|
|
20
|
+
params = {}
|
|
21
|
+
if site_url is not None:
|
|
22
|
+
params["siteUrl"] = site_url
|
|
23
|
+
try:
|
|
24
|
+
result = api.session.rest_get(url, params=params)
|
|
25
|
+
except WebexError as e:
|
|
26
|
+
handle_rest_error(e)
|
|
27
|
+
if output == "json":
|
|
28
|
+
print_json(result)
|
|
29
|
+
else:
|
|
30
|
+
if isinstance(result, dict):
|
|
31
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
32
|
+
elif isinstance(result, list):
|
|
33
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
34
|
+
else:
|
|
35
|
+
print_json(result)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@app.command("update")
|
|
40
|
+
def update(
|
|
41
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
42
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
43
|
+
):
|
|
44
|
+
"""Update Meeting Common Settings Configuration\n\nExample --json-body:\n '{"siteOptions":{"allowCustomPersonalRoomURL":true},"defaultSchedulerOptions":{"entryAndExitTone":"NoTone","telephonySupport":"None","joinTeleconfNotPress1":true,"tollFree":true,"VoIP":true},"scheduleMeetingOptions":{"emailReminders":true},"securityOptions":{"joinBeforeHost":true,"audioBeforeHost":true,"firstAttendeeAsPresenter":true,"unlistAllMeetings":true,"requireLoginBeforeAccess":true,"allowMobileScreenCapture":true,"requireStrongPassword":true,"passwordCriteria":{"mixedCase":"...","minLength":"...","minNumeric":"...","minAlpha":"...","minSpecial":"...","disallowDynamicWebText":"...","disallowList":"...","disallowValues":"..."}}}'."""
|
|
45
|
+
api = get_api(debug=debug)
|
|
46
|
+
url = f"https://webexapis.com/v1/admin/meeting/config/commonSettings"
|
|
47
|
+
if json_body:
|
|
48
|
+
body = json.loads(json_body)
|
|
49
|
+
else:
|
|
50
|
+
body = {}
|
|
51
|
+
try:
|
|
52
|
+
result = api.session.rest_patch(url, json=body)
|
|
53
|
+
except WebexError as e:
|
|
54
|
+
handle_rest_error(e)
|
|
55
|
+
typer.echo(f"Updated.")
|
|
56
|
+
|
|
57
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
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-slido.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("list")
|
|
12
|
+
def cmd_list(
|
|
13
|
+
session_org_id: str = typer.Option(..., "--session-org-id", help="Webex organization UUID."),
|
|
14
|
+
session_id: str = typer.Option(..., "--session-id", help="Webex meeting instance ID (`{meetingSeriesId}_I_{conferenceI"),
|
|
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
|
+
"""List Compliance Events."""
|
|
21
|
+
api = get_api(debug=debug)
|
|
22
|
+
url = f"https://webexapis.com/v1/slido/compliance/events"
|
|
23
|
+
params = {}
|
|
24
|
+
if session_org_id is not None:
|
|
25
|
+
params["sessionOrgId"] = session_org_id
|
|
26
|
+
if session_id is not None:
|
|
27
|
+
params["sessionId"] = session_id
|
|
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("items", 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
|
+
|
|
@@ -0,0 +1,92 @@
|
|
|
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-summaries.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("list")
|
|
12
|
+
def cmd_list(
|
|
13
|
+
meeting_id: str = typer.Option(None, "--meeting-id", help="Unique identifier for the [meeting instance](/docs/meetings#"),
|
|
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 Summary by Meeting ID."""
|
|
20
|
+
api = get_api(debug=debug)
|
|
21
|
+
url = f"https://webexapis.com/v1/meetingSummaries"
|
|
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
|
+
result = None
|
|
30
|
+
try:
|
|
31
|
+
result = api.session.rest_get(url, params=params)
|
|
32
|
+
except WebexError as e:
|
|
33
|
+
handle_rest_error(e)
|
|
34
|
+
result = result or []
|
|
35
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
36
|
+
if output == "json":
|
|
37
|
+
print_json(items)
|
|
38
|
+
else:
|
|
39
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@app.command("list-meeting-summaries")
|
|
44
|
+
def list_meeting_summaries(
|
|
45
|
+
meeting_id: str = typer.Option(None, "--meeting-id", help="Unique identifier for the [meeting instance](/docs/meetings#"),
|
|
46
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
47
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
48
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
49
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
50
|
+
):
|
|
51
|
+
"""Get Summary For Compliance Officer."""
|
|
52
|
+
api = get_api(debug=debug)
|
|
53
|
+
url = f"https://webexapis.com/v1/admin/meetingSummaries"
|
|
54
|
+
params = {}
|
|
55
|
+
if meeting_id is not None:
|
|
56
|
+
params["meetingId"] = meeting_id
|
|
57
|
+
if limit > 0:
|
|
58
|
+
params["max"] = limit
|
|
59
|
+
if offset > 0:
|
|
60
|
+
params["start"] = offset
|
|
61
|
+
result = None
|
|
62
|
+
try:
|
|
63
|
+
result = api.session.rest_get(url, params=params)
|
|
64
|
+
except WebexError as e:
|
|
65
|
+
handle_rest_error(e)
|
|
66
|
+
result = result or []
|
|
67
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
68
|
+
if output == "json":
|
|
69
|
+
print_json(items)
|
|
70
|
+
else:
|
|
71
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@app.command("delete")
|
|
76
|
+
def delete(
|
|
77
|
+
summary_id: str = typer.Argument(help="summaryId"),
|
|
78
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
79
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
80
|
+
):
|
|
81
|
+
"""Delete a Summary."""
|
|
82
|
+
if not force:
|
|
83
|
+
typer.confirm(f"Delete {summary_id}?", abort=True)
|
|
84
|
+
api = get_api(debug=debug)
|
|
85
|
+
url = f"https://webexapis.com/v1/meetingSummaries/{summary_id}"
|
|
86
|
+
try:
|
|
87
|
+
api.session.rest_delete(url)
|
|
88
|
+
except WebexError as e:
|
|
89
|
+
handle_rest_error(e)
|
|
90
|
+
typer.echo(f"Deleted: {summary_id}")
|
|
91
|
+
|
|
92
|
+
|
|
@@ -0,0 +1,233 @@
|
|
|
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-tracking-codes.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("list")
|
|
12
|
+
def cmd_list(
|
|
13
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site which the API retrieves the tracking c"),
|
|
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 Tracking Codes."""
|
|
20
|
+
api = get_api(debug=debug)
|
|
21
|
+
url = f"https://webexapis.com/v1/admin/meeting/config/trackingCodes"
|
|
22
|
+
params = {}
|
|
23
|
+
if site_url is not None:
|
|
24
|
+
params["siteUrl"] = site_url
|
|
25
|
+
if limit > 0:
|
|
26
|
+
params["max"] = limit
|
|
27
|
+
if offset > 0:
|
|
28
|
+
params["start"] = offset
|
|
29
|
+
result = None
|
|
30
|
+
try:
|
|
31
|
+
result = api.session.rest_get(url, params=params)
|
|
32
|
+
except WebexError as e:
|
|
33
|
+
handle_rest_error(e)
|
|
34
|
+
result = result or []
|
|
35
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
36
|
+
if output == "json":
|
|
37
|
+
print_json(items)
|
|
38
|
+
else:
|
|
39
|
+
print_table(items, columns=[('Name', 'name'), ('Site URL', 'siteUrl'), ('Service', 'service')], limit=limit)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@app.command("create")
|
|
44
|
+
def create(
|
|
45
|
+
name: str = typer.Option(None, "--name", help="(required) Name for tracking code. The name cannot be empty and the max"),
|
|
46
|
+
site_url: str = typer.Option(None, "--site-url", help="(required) Site URL for the tracking code."),
|
|
47
|
+
input_mode: str = typer.Option(None, "--input-mode", help="(required) Choices: text, select, editableSelect, hostProfileSelect"),
|
|
48
|
+
host_profile_code: str = typer.Option(None, "--host-profile-code", help="(required) Choices: optional, required, adminSet, notUsed"),
|
|
49
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
50
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
51
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
52
|
+
):
|
|
53
|
+
"""Create a Tracking Code\n\nExample --json-body:\n '{"name":"...","siteUrl":"...","options":[{"value":"...","defaultValue":"..."}],"inputMode":"text","hostProfileCode":"optional","scheduleStartCodes":[{"service":"...","type":"..."}]}'."""
|
|
54
|
+
api = get_api(debug=debug)
|
|
55
|
+
url = f"https://webexapis.com/v1/admin/meeting/config/trackingCodes"
|
|
56
|
+
if json_body:
|
|
57
|
+
body = json.loads(json_body)
|
|
58
|
+
else:
|
|
59
|
+
body = {}
|
|
60
|
+
if name is not None:
|
|
61
|
+
body["name"] = name
|
|
62
|
+
if site_url is not None:
|
|
63
|
+
body["siteUrl"] = site_url
|
|
64
|
+
if input_mode is not None:
|
|
65
|
+
body["inputMode"] = input_mode
|
|
66
|
+
if host_profile_code is not None:
|
|
67
|
+
body["hostProfileCode"] = host_profile_code
|
|
68
|
+
_missing = [f for f in ['name', 'siteUrl', 'inputMode', 'hostProfileCode'] if f not in body or body[f] is None]
|
|
69
|
+
if _missing:
|
|
70
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
71
|
+
raise typer.Exit(1)
|
|
72
|
+
try:
|
|
73
|
+
result = api.session.rest_post(url, json=body)
|
|
74
|
+
except WebexError as e:
|
|
75
|
+
handle_rest_error(e)
|
|
76
|
+
if output == "json":
|
|
77
|
+
print_json(result)
|
|
78
|
+
elif isinstance(result, dict) and "id" in result:
|
|
79
|
+
typer.echo(f"Created: {result['id']}")
|
|
80
|
+
elif not result or result == {}:
|
|
81
|
+
typer.echo("Created.")
|
|
82
|
+
else:
|
|
83
|
+
print_json(result)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@app.command("show")
|
|
88
|
+
def show(
|
|
89
|
+
tracking_code_id: str = typer.Argument(help="trackingCodeId"),
|
|
90
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site which the API retrieves the tracking c"),
|
|
91
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
92
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
93
|
+
):
|
|
94
|
+
"""Get a Tracking Code."""
|
|
95
|
+
api = get_api(debug=debug)
|
|
96
|
+
url = f"https://webexapis.com/v1/admin/meeting/config/trackingCodes/{tracking_code_id}"
|
|
97
|
+
params = {}
|
|
98
|
+
if site_url is not None:
|
|
99
|
+
params["siteUrl"] = site_url
|
|
100
|
+
try:
|
|
101
|
+
result = api.session.rest_get(url, params=params)
|
|
102
|
+
except WebexError as e:
|
|
103
|
+
handle_rest_error(e)
|
|
104
|
+
if output == "json":
|
|
105
|
+
print_json(result)
|
|
106
|
+
else:
|
|
107
|
+
if isinstance(result, dict):
|
|
108
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
109
|
+
elif isinstance(result, list):
|
|
110
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
111
|
+
else:
|
|
112
|
+
print_json(result)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@app.command("update")
|
|
117
|
+
def update(
|
|
118
|
+
name: str = typer.Option(None, "--name", help="Name for tracking code. The name cannot be empty and the max"),
|
|
119
|
+
site_url: str = typer.Option(None, "--site-url", help="Site URL for the tracking code."),
|
|
120
|
+
input_mode: str = typer.Option(None, "--input-mode", help="Choices: text, select, editableSelect, hostProfileSelect"),
|
|
121
|
+
host_profile_code: str = typer.Option(None, "--host-profile-code", help="Choices: optional, required, adminSet, notUsed"),
|
|
122
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
123
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
124
|
+
):
|
|
125
|
+
"""Update a Tracking Code\n\nExample --json-body:\n '{"name":"...","siteUrl":"...","options":[{"value":"...","defaultValue":"..."}],"inputMode":"text","hostProfileCode":"optional","scheduleStartCodes":[{"service":"...","type":"..."}]}'."""
|
|
126
|
+
api = get_api(debug=debug)
|
|
127
|
+
url = f"https://webexapis.com/v1/admin/meeting/config/trackingCodes/{trackingCodeId}"
|
|
128
|
+
if json_body:
|
|
129
|
+
body = json.loads(json_body)
|
|
130
|
+
else:
|
|
131
|
+
body = {}
|
|
132
|
+
if name is not None:
|
|
133
|
+
body["name"] = name
|
|
134
|
+
if site_url is not None:
|
|
135
|
+
body["siteUrl"] = site_url
|
|
136
|
+
if input_mode is not None:
|
|
137
|
+
body["inputMode"] = input_mode
|
|
138
|
+
if host_profile_code is not None:
|
|
139
|
+
body["hostProfileCode"] = host_profile_code
|
|
140
|
+
try:
|
|
141
|
+
result = api.session.rest_put(url, json=body)
|
|
142
|
+
except WebexError as e:
|
|
143
|
+
handle_rest_error(e)
|
|
144
|
+
typer.echo(f"Updated.")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@app.command("delete")
|
|
149
|
+
def delete(
|
|
150
|
+
tracking_code_id: str = typer.Argument(help="trackingCodeId"),
|
|
151
|
+
site_url: str = typer.Option(..., "--site-url", help="URL of the Webex site from which the API deletes the trackin"),
|
|
152
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
153
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
154
|
+
):
|
|
155
|
+
"""Delete a Tracking Code."""
|
|
156
|
+
if not force:
|
|
157
|
+
typer.confirm(f"Delete {tracking_code_id}?", abort=True)
|
|
158
|
+
api = get_api(debug=debug)
|
|
159
|
+
url = f"https://webexapis.com/v1/admin/meeting/config/trackingCodes/{tracking_code_id}"
|
|
160
|
+
params = {}
|
|
161
|
+
if site_url is not None:
|
|
162
|
+
params["siteUrl"] = site_url
|
|
163
|
+
try:
|
|
164
|
+
api.session.rest_delete(url, params=params)
|
|
165
|
+
except WebexError as e:
|
|
166
|
+
handle_rest_error(e)
|
|
167
|
+
typer.echo(f"Deleted: {tracking_code_id}")
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@app.command("list-tracking-codes")
|
|
172
|
+
def list_tracking_codes(
|
|
173
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site from which the API retrieves the track"),
|
|
174
|
+
person_id: str = typer.Option(None, "--person-id", help="Unique identifier for the user whose tracking codes are bein"),
|
|
175
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
176
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
177
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
178
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
179
|
+
):
|
|
180
|
+
"""Get User Tracking Codes."""
|
|
181
|
+
api = get_api(debug=debug)
|
|
182
|
+
url = f"https://webexapis.com/v1/admin/meeting/userconfig/trackingCodes"
|
|
183
|
+
params = {}
|
|
184
|
+
if site_url is not None:
|
|
185
|
+
params["siteUrl"] = site_url
|
|
186
|
+
if person_id is not None:
|
|
187
|
+
params["personId"] = person_id
|
|
188
|
+
if limit > 0:
|
|
189
|
+
params["max"] = limit
|
|
190
|
+
if offset > 0:
|
|
191
|
+
params["start"] = offset
|
|
192
|
+
result = None
|
|
193
|
+
try:
|
|
194
|
+
result = api.session.rest_get(url, params=params)
|
|
195
|
+
except WebexError as e:
|
|
196
|
+
handle_rest_error(e)
|
|
197
|
+
result = result or []
|
|
198
|
+
items = result.get("trackingCodes", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
199
|
+
if output == "json":
|
|
200
|
+
print_json(items)
|
|
201
|
+
else:
|
|
202
|
+
print_table(items, columns=[('Name', 'name'), ('Site URL', 'siteUrl'), ('Service', 'service')], limit=limit)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@app.command("update-tracking-codes")
|
|
207
|
+
def update_tracking_codes(
|
|
208
|
+
site_url: str = typer.Option(None, "--site-url", help="Site URL for the tracking code."),
|
|
209
|
+
person_id: str = typer.Option(None, "--person-id", help="Unique identifier for the user. At least one parameter of `p"),
|
|
210
|
+
email: str = typer.Option(None, "--email", help="Email address for the user. At least one parameter of `perso"),
|
|
211
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
212
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
213
|
+
):
|
|
214
|
+
"""Update User Tracking Codes\n\nExample --json-body:\n '{"siteUrl":"...","personId":"...","email":"...","trackingCodes":[{"name":"...","value":"..."}]}'."""
|
|
215
|
+
api = get_api(debug=debug)
|
|
216
|
+
url = f"https://webexapis.com/v1/admin/meeting/userconfig/trackingCodes"
|
|
217
|
+
if json_body:
|
|
218
|
+
body = json.loads(json_body)
|
|
219
|
+
else:
|
|
220
|
+
body = {}
|
|
221
|
+
if site_url is not None:
|
|
222
|
+
body["siteUrl"] = site_url
|
|
223
|
+
if person_id is not None:
|
|
224
|
+
body["personId"] = person_id
|
|
225
|
+
if email is not None:
|
|
226
|
+
body["email"] = email
|
|
227
|
+
try:
|
|
228
|
+
result = api.session.rest_put(url, json=body)
|
|
229
|
+
except WebexError as e:
|
|
230
|
+
handle_rest_error(e)
|
|
231
|
+
typer.echo(f"Updated.")
|
|
232
|
+
|
|
233
|
+
|