Sie sind auf Seite 1von 67

Cisco

Connect
Moscow, 2017

Digitalization: here
and now
Part 2. API Cisco Meeting Server. When
you need to use it. API use in scripts
python. Sharing an example with In-room
control.

Sergey Yutsaytis
on collaboration technology consultant

© 2017 Cisco and / or its affiliates. All rights reserved.


CMS uses the API to customize non-standard Almost all server-based applications and services now
configurations for integration with other support some form of API, but the API is usually used for
solutions, and to provide their own development needs (eg integration with other
products of the manufacturer). Therefore, using the API can
be licensed separately or it may have limited capabilities.
information to other devices and applications. Acano initially decided to support open APIs in which any
action is available without any royalties or other fees and
payments, even on the demo VM. This tradition we will
CMS supports RESTful API or 'Rest API' continue with the CMS.
(abbr. From
Eng. Representational State Transfer -
"Representational State Transfer")
API calls
Working with API is typically performed through You can use different programming languages ​of
execution of the call ( 'API Call') APIs to work with, but it so happened historically
that Acano programmers mainly used Python.
You can for example make an API call to There are examples of using Java, Powershell,
create a conference (Space) A lot of API calls can Curl, Ruby, HTTP, PHP, and many others.
be made simultaneously, which allows, for
example, to automate their startup scripts.
Consistent implementation of API calls in a part of
the script can be significantly faster than manually.
You can perform API calls directly from your
browser using extensions like POSTer,
POSTman and Advanced Rest Client.
Available API calls
• / accessQuery / DialTransforms / <dial transform id> • / Participants / <participant id> / callLegs

• / callBrandingProfiles • / dtmfProfiles • / System / alarms

• / CallBrandingProfiles / <call branding profile id> / DtmfProfiles / < dtmf profile id> • / System / configuration / cluster

• / callBridges • / directorySearchLocations • / System / configuration / xmpp

• / CallBridges / <call bridge id> • / DirectorySearchLocations / <directory search location id> • / System / database

• / calls • / forwardingDialPlanRules • / System / status

• / Calls / <call id> • / ForwardingDialPlanRules / <forwarding dial plan rule id> • / System / profiles

• / Calls / <call id> / callLegs • / inboundDialPlanRules • / System / cdrReceiver

• / Calls / <call id> / participants • / InboundDialPlanRules / <inbound dial plan rule id> • / tenants

• / callLegs • / outboundDialPlanRules • / Tenants / <tenant id>

• / CallLegs / <callLeg id> • / OutboundDialPlanRules / <outbound dial plan rule id> • / turnServers

/ CallLegs / <callLeg id> / callLegProfileTrace • / ivrs • / TurnServers / <turn server id>

/ callLegProfiles • / Ivrs / <ivr id> • / TurnServers / <turn server id> / status

• / CallLegProfiles / <call leg profile id> / ivrBrandingProfiles / users

/ CallLegProfiles / <call leg profile id> / usage / IvrBrandingProfiles / <ivr branding profile id> • / Users / <user id>

• / callProfiles • / ldapMappings • / Users / <user id> / usercoSpaces

/ CallProfiles / <call profile id> • / LdapMapping / <ldap mapping id> / userProfiles

• / coSpaces • / ldapServers / UserProfiles / <user profile id>

• / CoSpaces / <coSpace id> • / LdapServers / <ldap server id> / webBridges

• / CoSpaces / <coSpace id> / coSpaceUsers • / ldapSources • / WebBridges / <web bridge id>

• / CoSpaces / <coSpace id> / coSpaceUsers / <coSpaceUser id> • / LdapSources / <ldap source id> / WebBridges / <web bridge id> / updateCustomization

• / CoSpaces / <coSpace id> / messages • / ldapSyncs • Other ,,,,

• / CoSpaces / <coSpace id> / accessMethods • / LdapSyncs / <ldap sync id>

/ CoSpaces / <coSpace id> / accessMethods / <access method id> • / participants

• / dialTransforms • / Participants / <participant id>


coSpaceUsers
User (Id, Jd)
callLegProfile accessMethods Messages (post)
coSpace
Message, from
canDestroy URI / passcode / callID Secret (delete) minAge,
Uri callId canAddRemoveMember
Scope maxAge
Owner (Id, Jd) canChangeName canChangeUri
canChangeCallId
canChangePasscode
Secret
canPostMessage
defaultLayout
canRemoveSelf
canDeleteAllMessages

Call Leg Profile


needsActivation
system / profiles defaultLayout changeLayoutAllowed participantLabels presentationDisplayMode
presentationContributionAllowed presentationViewingAllowed endCallAllowed muteOthersAllowed
videoMuteOthersAllowed muteSelfAllowed videoMuteSelfAllowed joinToneParticipantThreshold
callLegProfile leaveToneParticipantThreshold videoMode rxAudioMute txAudioMute rxVideoMute
callProfile
dtmfProfile
txVideoMute sipMediaEncryption audioPacketSizeMs deactivationMode deactivationModeTime
telepresenceCallsAllowed sipPresentationChannelEnabled bfcpMode
• Solving specific A large number of integrations for

Customers of different tasks or oriented to work with them

own products

• What's been done:

- Created thousands of Spaces using CSV files for Customers

do not use LDAP

What has been done and - Implemented projects with automatic creation of Spaces for Multi-

what can be done with the


way technology

- Changing PIN codes for each Space on the server

use of CMS (ACANO) API? - By pressing change the screen layout for all

connected conference participants, except for the presenter

- Integrated with SFDC, creating the Space for each user

- Integration with Amazon Echo (Alexa) for conference management

voice commands

- Integration with the Cisco Spark for upravleniyal Spaces through Spark

messages

IFTTT integration using different channels


7
-

- And much more…


Example - Amazon Echo for controlling conferences

In the first version Acano integration with Amazon Echo


allowed users through voice commands to start the
meeting, make outgoing calls, manage the on-screen
layouts, switch off the voice, video and disable subscribers
to complete the conference.
CMS API Guide

Guide CMS API Programming

http://www.cisco.com/c/en/us/support/conferencing/meetingserver/products-programming-reference-guides-list.html

http://www.cisco.com/c/dam/en/us/td/docs/conferencing/ciscoMeetingServ er / Reference_Guides
/ Version-2-1 / Cisco-Meeting-Server-API-Reference-
Guide-2-1.pdf

https://www.acano.com/support/documentation/

We recommend using the latest version of API management product.

The manual contains all the necessary materials and instructions supported in API CMS.

Until now, there was no change in the API terms of use or change their plans. A complete set of
commands is available in demo versions, trial version Acano and not licensed.
We need to operate with 4 types of queries:

GET - output (read) information

POST - create a new record

PUT - edit an existing entry

DELETE - delete an existing entry


Instruments
• Beb browser
• Personally, I recommend Chrome: http://getchrome.com
• python 3.5+
• https://www.python.org/downloads/release/python-351/
• Editor
• Any convenient to you the text editor (I advise you to choose the understanding of the key operators of high-level languages ​- such as
TextWrangler) or Integrated Development Environment (I use PyCharm)
• You can use IDLE, which installs Python
• Git
• http://git-scm.com/
• Postman
• Download from the Chrome Web Store, or (recommend this option) - stand-alone version http://www.getpostman.com/
the application can be downloaded, postman collection for CMS2.1 and code examples from my Exchange mailbox file:
https://cisco.box.com/v/sergey
Postman - the use of the collections:
We find the default CallProfile:
Turn it messageBoard:
Check the recorded video:
<? Xml version = "1.0"?>
<DtmfProfile id = "722b45a2-1784-4060-bdf2-1d88df5c7818">
<muteSelfAudio> </ muteSelfAudio>
dtmfProfile :
<UnmuteSelfAudio> 0 </ unmuteSelfAudio>
<ToggleMuteSelfAudio> </ toggleMuteSelfAudio> <lockCall> </
lockCall> <unlockCall> </ unlockCall>

<MuteAllExceptSelfAudio> </ muteAllExceptSelfAudio>


<unmuteAllExceptSelfAudio> </ unmuteAllExceptSelfAudio> <endCall> </
endCall>
<NextLayout> 8 </ nextLayout> <previousLayout>
2 </ previousLayout> <startRecording> * 1 </
startRecording> <stopRecording> * 0 </
stopRecording>
<StartStreaming> </ startStreaming> <stopStreaming> </
stopStreaming> <allowAllMuteSelf> </ allowAllMuteSelf>
<cancelAllowAllMuteSelf> </ cancelAllowAllMuteSelf>

<AllowAllPresentationContribution> </ allowAllPresentationContribution>


<cancelAllowAllPresentationContribution> </ cancelAllowAllPresentationContribution> <muteAllNewAudio>
</ muteAllNewAudio> <unmuteAllNewAudio> </ unmuteAllNewAudio> <defaultMuteAllNewAudio> </
defaultMuteAllNewAudio>

<MuteAllNewAndAllExceptSelfAudio> </ muteAllNewAndAllExceptSelfAudio>


<unmuteAllNewAndAllExceptSelfAudio> </ unmuteAllNewAndAllExceptSelfAudio> </ dtmfProfile>
SallLegProfile :

https://10.100.1.227:9443/api/v1/callLegProfiles/ac0485e3-a3b7-47cf-91fe-ffa25ea5d795

<? Xml version = "1.0"?>


<CallLegProfile id = "ac0485e3-a3b7-47cf-91fe-ffa25ea5d795"> <defaultLayout>
onePlusFive </ defaultLayout> - screen layout
<ParticipantLabels> true </ participantLabels> - show the names of the participants
<SipMediaEncryption> optional </ sipMediaEncryption>
<muteOthersAllowed> true </ muteOthersAllowed> - allow mute other participants
<VideoMuteOthersAllowed> true </ videoMuteOthersAllowed> - to allow other participants to turn off the video
<MuteSelfAllowed> true </ muteSelfAllowed> <videoMuteSelfAllowed> true </
videoMuteSelfAllowed> <disconnectOthersAllowed> true </
disconnectOthersAllowed> - allow to disconnect other participants
<TelepresenceCallsAllowed> false </ telepresenceCallsAllowed>
<sipPresentationChannelEnabled> true </ sipPresentationChannelEnabled>
<changeLayoutAllowed> true </ changeLayoutAllowed> - resolve to change their screen layout
<BfcpMode> serverAndClient </ bfcpMode> </
callLegProfile>
Management of the participants from a video of the application window:
Planning CMS 2.0 c TMS 15.3
Making an outgoing call
Renewals
conference

Completing the Add / Remove


Conference
Setting the administrator or operator rights conference owner

GET https://10.100.1.227:9443/api/v1/Cospaces

<CoSpace id = "4a5d366d-1b73-4c55-baa1-c323e90d70cb">
<Name> TMS_Scheduled_Meeting_5590001 </ name>
<autoGenerated> false </ autoGenerated> <uri> 5,590,001 </ uri>
<callId> 5,590,001 </ callId> </ coSpace>

POST https://10.100.1.227:9443/api/v1/Cospaces/ four a5d366d-1b73-4c55-baa1-c323e90d70cb / coSpaceUsers

userJid = admin @ domain


lecturer mode
In the current version 2.0 is not implemented CMS lecturer mode.

But, if the lecturer and the audience is allowed to connect with different
numbers (the URI) - it can be implemented through the API (as of version 2.1 -
different password (or password / no password))
CMS

Lecturer: calls to URI 5500@example.com, layout - quad, sees all the participants,
the microphone is active

Guest: calls to URI 5600@example.com, one large window with the speaker (lecturer),
the microphone is turned off, if the Speaker is off
- Video and voice are not received by the server
lecturer mode
1. Create a new space with the lecturer account profile

2. Create a profile for a compound Lecturer (Call Leg Profile): POST https://example.com/api/v1/callLegProfiles defaultLayout = allEqual

3. Create a connection profile for the guest: POST https://example.com/api/v1/callLegProfiles


needsActivation = true & defaultLayout = speakerOnly & rxAudioMute = true & deactivationMode = deactivate

4. Learn identifiers connection profiles (Call Leg Profile): GET https://example.com/api/v1/callLegProfiles

Assume that the Call Leg Profile ID lecturer: 360b40bf-4c7d-41ff-a355-496c0e720649


Call Leg Profile Guest ID: 5546a47f-262a-4399-a799-0a03ddc2c66c

Learn identifier space (space ID): GET https://example.com/api/v1/coSpaces


Let's say that Space ID: 83b4f7d0-ffb7-4fbc-83c0-91ebe04f2af3

Create a connection method Lecturer (Access Method) with a URI and a Call ID 5500:

POST https: // example.com/api/v1/coSpaces/83b4f7d0-ffb7-4fbc-83c0-91ebe04f2af3/accessMethods

uri = 5500 & callLegProfile = 360b40bf-4c7d-41ff-a355-496c0e720649 & callID = 5500 (Access Method
ID: f3a7cf1a-961f-4fec-b19d-5db558851305)

Create a method of connecting guest (Access Method) with a URI and a Call ID 5600:

POST https://example.com/api/v1/coSpaces/83b4f7d0-ffb7-4fbc-83c0-91ebe04f2af3/accessMethods

uri = 5600 & callLegProfile = 5546a47f-262a-4399-a799-0a03ddc2c66c & callID = 5600 (Access Method ID: 056a58ee-12bc-404f-b863-834cba4707db)
How to make a Python REST call
Python requests Library

requests - HTTP library Python. The closest analogue - urllib2 .

It contains a built-in library urllib3 .

Homepage of the project - http://docs.python-requests.org

Set requests, you can use PIP: $ pip install requests

> > > r = requests . get ( 'Https://api.github.com/events' )

> > > r = requests . post ( 'Http://httpbin.org/post' , data = { 'Key' : 'Value' })

> > > r = requests . put ( 'Http://httpbin.org/put' , data = { 'Key' : 'Value' })

> > > r = requests . delete ( 'Http://httpbin.org/delete' )

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 31
Python requests Library
from pprint import pprint
import paramiko
import time
import re
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning # warning about not
requests.packages.urllib3.disable_warnings (InsecureRequestWarning) # Valid certificates

CMS_BASE = ' https://10.100.1.227:9443/api/v1/ ' # We set the basic parameters (e.g. IP)
CMS_HEADERS = { ' Content-type ' : 'Application / json' . 'Authorization' : "Basic YWRtaW46QzFzY28xMjM =" } # Ask login and password (take from the postman)

client = paramiko.SSHClient ()
client.set_missing_host_key_policy (paramiko.AutoAddPolicy ()) client.connect ( " 10.100.1.147 " . username = " admin " . password = " C1sco123 " ) # connection
to the server

channel = client.invoke_shell () channel.send ( ' xst SIP


Registration URI 1 \ n ' )
time.sleep ( 0.5 )
output = channel.recv ( 2000 )

Number = '' .join (re.findall ( r '\ w+@demo.cisco.ru' . str (Output)))


print ( ' number of video ' + '' . join (Number)) # The number of your video we will need to find its connection data

# calls = requests.get (CMS_BASE + ' calllegs' + '? Filter =' + Number, verify = False . headers = CMS_HEADERS)

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 32
Python requests Library
calls = requests.get (CMS_BASE + ' calllegs' + '? Filter =' + Number, verify = False . headers = CMS_HEADERS)

if calls.status_code == 200 : Pprint ( " this is what gave request.get: " +


calls.text)

# This is our callleg:


calleg = '' .join (re.findall ( r '<callLeg id = "(\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +)' . calls.text))
if len (Calleg)> 0 :

# Here we are connected to the conference, we learn all about connecting and conferences

callid = '' .join (re.findall ( r '<call> (\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +)' . calls.text)) pprint ( " connection ID " + calleg) channel.send ( ' xCommand UserInterface Extensions
Widget SetValueWidgetId: "info3" Value: "Connection ID ' + calleg + '' \ n ' )

pprint ( " connection identifier " + callid) channel.send ( ' xCommand UserInterface Extensions Widget SetValueWidgetId: "info4" Value: "Conference ID ' + callid +

' "\ N' )

def confinfo (a): return requests.get (CMS_BASE + ' calls / ' + a, verify = False . headers = CMS_HEADERS) confinf = confinfo (callid)
pprint ( " Information about the conference: " + confinf.text)

client.close ()

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 33
Encoding
<? Xml version = "1.0"?>
<CallLegs total = "4">
<CallLeg id = "9132036b-148f-49a6-9960-7bc90fabbbad"> <name> SX10
UGLICH 40210 </ name> <remoteParty> 40210@demo.cisco.ru </
remoteParty> <call> ce4a7f5f-4670-4ed8-b822 -3e28a0475678 </ call>
</ callLeg>

<CallLeg id = "ee4d87a6-f56e-41d5-bd7f-154f672e348d"> <name> SX20


KRASNODAR 40220 </ name> <remoteParty> 40220@demo.cisco.ru </
remoteParty> <call> ce4a7f5f-4670-4ed8-b822 -3e28a0475678 </ call>
</ callLeg>

<CallLeg id = "990a91a7-f571-40ac-8c58-55eb4edab6cf"> <name> Elena


Volkova </ name> <remoteParty> 1300@demo.cisco.ru </ remoteParty>
<call> ce4a7f5f-4670-4ed8-b822-3e28a0475678 </ call> </ callLeg>

<CallLeg id = "668bffaa-e813-4898-9088-2f671c9a4435"> <name> Petr


Petrov </ name>
<RemoteParty> 40043@demo.cisco.ru </ remoteParty> <call>
ce4a7f5f-4670-4ed8-b822-3e28a0475678 </ call> </ callLeg> </ callLegs>

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 34
Encoding
Encoding [ ' SX10 UGLICH 40210 ',' SX20
Р\ x92оРKRASNODAR
»ÐºÐ¾Ð²Ð ° ',' Ð \40220
x9fÐμÑ','\ Ð \ x95Ð
x82Ñ \ x80»ÐμнР° \ x82Ñ \ x80ов ']
Ð \ x9fÐμÑ

activelegs = requests.get (CMS_BASE + ' calls / ' + callid + '/ callLegs' . verify = False . headers = CMS_HEADERS) activelegs.encoding = ' utf-8
'

[ 'SX10 UGLICH 40210', 'SX20 KRASNODAR 40220', 'Elena Volkova', 'Peter Petrov']

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 35
Python requests Library - the encoding

calls = requests.get (CMS_BASE + ' calllegs' + '? Filter =' + Number, verify = False . headers = CMS_HEADERS)

calls.encoding = ' utf-8 ' # we set the encoding

if calls.status_code == 200 : Pprint ( " this is what gave request.get: " +


calls.text)

# This is our callleg:


calleg = '' .join (re.findall ( r '<callLeg id = "(\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +)' . calls.text))
if len (Calleg)> 0 :

# Here we are connected to the conference, we learn all about connecting and conferences

callid = '' .join (re.findall ( r '<call> (\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +)' . calls.text)) pprint ( " connection ID " + calleg) channel.send ( ' xCommand UserInterface Extensions
Widget SetValueWidgetId: "info3" Value: "Connection ID ' + calleg + '' \ n ' )

pprint ( " connection identifier " + callid) channel.send ( ' xCommand UserInterface Extensions Widget SetValueWidgetId: "info4" Value: "Conference ID ' + callid + '' \ n ' )

def confinfo (a): return requests.get (CMS_BASE + ' calls / ' + a, verify = False . headers = CMS_HEADERS) confinf = confinfo (callid)
pprint ( " Information about the conference: " + confinf.text) client.close ()

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 36
What we have learned about how to connect?
<CallLegs '' total = "1"> <callLeg id = " bdac73d6-ec81-422a-bdb3-eadefb234353 ">
<Name> SX20 '' Room - '' Moscow </ name> <remoteParty> 40220@demo.cisco.ru </ remoteParty> <call> 32a41a3a-076d-4a25-b485db9f1f1ea067 </ call> </ callLeg> </
callLegs> ')

calleg = '' .join (re.findall ( r '<callLeg id = "(\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +)' . calls.text))

ID: bdac73d6-ec81-422a-bdb3-eadefb234353

callid = '' .join (re.findall ( r '<call> (\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +)' . calls.text)) Our Callleg

Our Call ID: 32a41a3a-076d-4a25-b485-db9f1f1ea067

requests.get (CMS_BASE + ' calls / ' + callid, verify = False . headers = CMS_HEADERS)

'Information about the conference: <? Xml version = "1.0"?> <Call' 'id = "32a41a3a-076d-4a25-b485-db9f1f1ea067"> <coSpace> 202a6e1c-b65b4c29-a2eb-234925419eb2 </
coSpace> <callCorrelator> 0704eef6-4c7c-4215-8903-
2459d1a1efb5 </ callCorrelator> <durationSeconds> 2428 </ durationSeconds> <numCallLegs> 15 </ numCallLegs> <maxCallLegs> 15 </ maxCallLegs
> <NumParticipantsLocal> 15 </ numParticipantsLocal> <locked> false </ locked> <recording> false </ recording> <streaming> false </ streaming> <all owAllMuteSelf> false </
allowAllMuteSelf> <allowAllPresentationContribution> false </ allowAllPresentationContribution> < messagePosition> mi ddle </ messagePosition> <messageDuration> 0 </
messageDuration> </ call> ')

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 37
Automation of routine operations, such as connecting a large number of participants in the conference call ID famous

Virtual = [ ' 1000 ' . '1001' . '1002' . '1003' . '1004' . '1005' . '1006' . '1007' . '1008' . '1009' . '1011' . '1014' . '1017' ] # Create an object type from the list of subscribers numbers

def autoconnect (action): # We specify the function that will be convenient to call for connecting / disconnecting all users list
global callid

if action == " on " : # connect subscribers from the list


for element in Virtual: pprint (element) # We keep track of the
script
connect = requests.get (CMS_BASE + ' calllegs? filter = ' + element, verify = False . headers = CMS_HEADERS) # check whether it is connected by the server?
if '' . join (re.findall ( r'callLegs total = "(\ d) ' . connect.text)) == ' 0 ' :

# connecting operation
requests.post (CMS_BASE + ' calls / ' + callid + '/ calllegs' . data = " remoteParty = " + element + "@ str.ru " . verify = False . headers = CMS_HEADERS)

if action == " off " : # disable users from a list


for element in Virtual: pprint
(element)
connect = requests.get (CMS_BASE + ' calllegs? filter = ' + element, verify = False . headers = CMS_HEADERS)
if '' . join (re.findall ( r'callLegs total = "(\ d) ' . connect.text))! = ' 0 ' :
calllegidcurrent = '' .join (re.findall ( r'callLeg id = "(\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +) ' . connect.text)) pprint (calllegidcurrent)
requests.delete (CMS_BASE + ' calllegs / ' + calllegidcurrent, verify = False . headers = CMS_HEADERS)

autoconnect ( " off " ) # You can wait for the command from the CLI, but I did not do to minimize code

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 38
Automate routine tasks, such as setting the mode for the participants in the conference call ID with a known

def findlegs ():


offset = 0

activelegs = requests.get (CMS_BASE + ' calls / ' + callid + '/ callLegs' . verify = False . headers = CMS_HEADERS)

print (Activelegs.text) collegstotal = int ( '' .join (re.findall ( r'callLegs total = "(\ d +) ' . activelegs.text))) calllegs
= re.findall ( r'callLeg id = "(\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +) ' . activelegs.text)

if len (Calllegs) <collegstotal:


offset = offset + ten
activelegs = requests.get (CMS_BASE + ' calls / ' + callid + '/ callLegs? offset = ' + str (Offset), verify = False . headers = CMS_HEADERS)

calllegs = calllegs + re.findall ( r'callLeg id = "(\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +) ' . activelegs.text)

print (Calllegs)

findlegs ()

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 39
Automate routine tasks, such as setting the mode for the participants in the conference call ID with a known

<? Xml version = "1.0"?> <CallLegs total = "15"> <callLeg id = "0d20279c-d792-4032-9206-


8bf3786fca04 "> <name> </ name> <remoteParty> 1000@str.ru </ remoteParty> <call> 32a41a3a-076d-4a25-b485-db9f1f1ea067 </ call> </ callLeg> <callLeg id =" 0e8d0458-0172
-4a6a-bf3d-c26e8f0863b8 "> <name> </ name> <remoteParty> 1004@str.ru </ remoteParty> <call> 32a41a3a-076d-4a25-b485db9f1f1ea067 </ call> </ callLeg> <callLeg id ="
113ef87c-8925-4929-bf10-
467649f53ed7 "> <name> </ name> <remoteParty> 1001@str.ru </ remoteParty> <call> 32a41a3a-076d-4a25-b485-db9f1f1ea067 </ call> </ callLeg> <callLeg id =" 3105f6b5-d3ca
-4c3b-9e6c-2e6159284fa4 "> <name> </ name> <remoteParty> 1007@str.ru </ remoteParty> <call> 32a41a3a-076d-4a25-b485db9f1f1ea067 </ call> </ callLeg> <callLeg id ="
80737b65-1385-463d-aa90-
64a52f03e60f "> <name> </ name> <remoteParty> 1011@str.ru </ remoteParty> <call> 32a41a3a-076d-4a25-b485-db9f1f1ea067 </ call> </ callLeg> <callLeg id =" aefb65b6-6043
-4603-b6a9-7cd0182095a2 "> <name> </ name> <remoteParty> 1005@str.ru </ remoteParty> <call> 32a41a3a-076d-4a25-b485db9f1f1ea067 </ call> </ callLeg> <callLeg id ="
af961c3b-e8e3-4daa-884d-
89e29a32a4d8 "> <name> </ name> <remoteParty> 1009@str.ru </ remoteParty> <call> 32a41a3a-076d-4a25-b485-db9f1f1ea067 </ call> </ callLeg> <callLeg id =" b882fdf6-3d4c
-46e7-b3b6-9d0f0b87475f "> <name> </ name> <remoteParty> 1014@str.ru </ remoteParty> <call> 32a41a3a-076d-4a25-b485db9f1f1ea067 </ call> </ callLeg> <callLeg id ="
c28d8918-c516-405f-a9db-
382db87de3b0 "> <name> </ name> <remoteParty> 1003@str.ru </ remoteParty> <call> 32a41a3a-076d-4a25-b485-db9f1f1ea067 </ call> </ callLeg> <callLeg id =" c45016cf-7812
-4c9f-8b95-a0eb024ebc4c "> <name> </ name> <remoteParty> 1017@str.ru </ remoteParty> <call> 32a41a3a-076d-4a25-b485db9f1f1ea067 </ call> </ callLeg> </ callLegs>

[ '0d20279c-d792-4032-9206-8bf3786fca04', '0e8d0458-0172-4a6a-bf3d-c26e8f0863b8', '113ef87c-8925-4929-bf10-467649f53ed7', '3105f6b5-d3ca-4c3b9e6c-2e6159284fa4', '80737b65-


1385-463d-aa90-64a52f03e60f ',' aefb65b6-6043-4603-b6a9-7cd0182095a2 ',' af961c3b-e8e3-4daa-884d-89e29a32a4d8 ',' b882fdf6-3d4c-46e7-b3b6-9d0f0b87475f ',' c28d8918-c516-
405f-a9db-382db87de3b0 ',' c45016cf-7812-4c9f-8b95-a0eb024ebc4c ',' d7cebcb4-799f-4ef8-90901ed25b0e2b7d ',' e73cb349-1281-4f47-a9e2-b228dbedceb5 ',' f7749b16-6173-46b1-ab1d-
4a85451269fc ',' bdac73d6-ec81-422a-bdb3-eadefb234353 ',' 0373aa04-8c1f-40d0-8f9a-b5f78f98fa21 ']

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 40
Information about connecting to the conference call ID and known operations with them, for example - to be installed over the
specific screen configuration

def findlegs ():


offset = 0

activelegs = requests.get (CMS_BASE + ' calls / ' + callid + '/ callLegs' . verify = False . headers = CMS_HEADERS)
print (Activelegs.text) collegstotal = int ( '' .join (re.findall ( r'callLegs total = "(\ d +) ' . activelegs.text))) calllegs =
re.findall ( r'callLeg id = "(\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +) ' . activelegs.text)

if len (Calllegs) <collegstotal: offset =


offset + ten
activelegs = requests.get (CMS_BASE + ' calls / ' + callid + '/ callLegs? offset = ' + str (Offset), verify = False . headers = CMS_HEADERS) calllegs = calllegs + re.findall ( r'callLeg
id = "(\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +) ' . activelegs.text)
print (Calllegs)
return calllegs # must be used to access the value of the variable from another function

def setlayout (L): calllegs = findlegs () Layout = [ ' speakerOnly ' . 'Telepresence' . 'Stacked' . 'AllEqual' . 'OnePlusN' . 'Automatic' . 'AllEqualQuarters' . 'AllEqualNinths' . 'AllEqualSixteenths' . 'AllEqualTwentyFifths' .

'OnePlusFive' . 'OnePlusSeven' . 'OnePlusNine' ] # Create a list of all existing configurations screens


# Apply the screen layout
# We organize and cycle through each calllegs, do not forget to compare with her (because you have to change everything except yourself)
pprint ( " Set the layout of all but himself - " + Layout [L]) i = 0

for element in calllegs:


if ! Calllegs [i] = calleg: # Here we check that callleg which we will carry out the operation does not coincide with our terminal callleg
requests.put (CMS_BASE + ' calllegs / ' + calllegs [i], data = " defaultLayout = " + Layout [L], verify = False . headers = CMS_HEADERS) pprint (calllegs [i]) i = i + one

setlayout ( 3 )

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 41
Parsing (JSON, XML)
Parsing content

• Why do it?

• parsing methods
• not parse the
• If the information is presented in easy to read format you

• Do-It-Yourself (DIY) string parsing ( what we have done so far)


• It is useful if the desired information is really just

• Creation or use of framework / libraries


• A lot of ready-made libraries and tools for all occasions available
Parsing and extracting information
Parsing and processing of the results

• foundation
• content
• Which is represented - Members? Books? the logging? the sample data? the access point?
• Driving - What is the order, form, and data requirements?
• Size - How large is the amount of information displayed? Maybe it's the size create problems?
• What you need
• The names of users and their e-mail addresses, X and Y coordinates, ID, and patient rooms
• How much you need to get records
• You have to count the number of records to obtain a representative sample, or all?

• Know that there are usually several ways of obtaining and processing content ..

• Various WEB library (urllib, urllib2, Requests, etc.)


• Different parsers JSON (JSON, SimpleJSON, UltraJSON, etc.)
• Different XML parsers (xml.etree.ElementTree, lxml, xml.dom.minidom etc.)
As the data is converted by Python default <-> JSON
< callLegs total = " 14" >
parsing XML < callLeg id = " 14076e5e-72fb-42ec-998a-7f0602687e41 " >
< name> </ name>
< remoteParty> 1011 @ str .ru </ remoteParty>

https: // {{MmpHost}} / Api / v1 / calllegs < call> 41 b79d90-9358-4b4d-952e-c4f6d0df2c09 </ Call>


</ callLeg>
< callLeg id = " 1bee0f35-7250-479a-b3de-3c026d3c1498 " >
<? Xml version = "1.0"?> <CallLegs total = "14"> <callLeg id = "14076e5e72fb-42ec-998a- < name> </ name>
< remoteParty> 1005 @ str .ru </ remoteParty>
7f0602687e41 "> <name> </ name> <remoteParty> 1011@str.ru </ re moteParty> < call> 41 b79d90-9358-4b4d-952e-c4f6d0df2c09 </ Call>
<call> 41b79d90-9358-4b4d-952e- </ callLeg>
c4f6d0df2c09 </ call> </ callLeg> <callLeg id = "1bee0f35-7250-479ab3de- < callLeg id = " 28dfbd95-a81a-40dc-849f-0c0efaec6b72 " >
< name> </ name>
3c026d3c1498 "> <name> </ name> <remoteParty> 1005@str.ru </ re moteParty> < remoteParty> 1003 @ str .ru </ remoteParty>
<call> 41b79d90-9358-4b4d-952e- < call> 41 b79d90-9358-4b4d-952e-c4f6d0df2c09 </ Call>
c4f6d0df2c09 </ call> </ callLeg> <callLeg id = "28dfbd95-a81a-40dc849f- </ callLeg>
< callLeg id = " 467772e0-f676-4784-b9bb-393a3a6e8a20 " >
0c0efaec6b72 "> <name> </ name> <remoteParty> 1003@str.ru </ rem oteParty> <call> < name> </ name>
41b79d90-9358-4b4d-952e- < remoteParty> 1001 @ str .ru </ remoteParty>
c4f6d0df2c09 </ call> </ callLeg> <callLeg id = "467772e0-f676-4784b9bb- < call> 41 b79d90-9358-4b4d-952e-c4f6d0df2c09 </ Call>
</ callLeg>
393a3a6e8a20 "> <name> </ name> <remoteParty> 1001@str.ru </ re moteParty> < callLeg id = " 609e2fe9-0577-4884-9eab-72f8165a58c1 " >
<call> 41b79d90-9358-4b4d-952e- < name> </ name>
c4f6d0df2c09 </ call> </ callLeg> <callLeg id = "609e2fe9-0577-48849eab- < remoteParty> 1008 @ str .ru </ remoteParty>
< call> 41 b79d90-9358-4b4d-952e-c4f6d0df2c09 </ Call>
72f8165a58c1 "> <name> </ name> <remoteParty> 1008@str.ru </ rem oteParty> <call> </ callLeg>
41b79d90-9358-4b4d-952e- < callLeg id = " 9338fa97-e95a-49e4-af04-34fc596ccf30 " >
c4f6d0df2c09 </ call> </ callLeg> <callLeg id = "9338fa97-e95a-49e4af04- < name> </ name>
< remoteParty> 1002 @ str .ru </ remoteParty>
34fc596ccf30 "> <name> </ name> <remoteParty> 1002@str.ru </ rem oteParty> </ < call> 41 b79d90-9358-4b4d-952e-c4f6d0df2c09 </ Call>
callLeg> </ callLegs> </ callLeg> </
callLegs>
XML parsing using xml.etree.ElementTree
https://docs.python.org/2/library/xml.etree.elementtree.html

def findlegs ():


offset = 0
activelegs = requests.get (CMS_BASE + ' calls / ' + callid + '/ callLegs' . verify = False . headers = CMS_HEADERS) activelegs.encoding = ' utf-8 '

calllegs = ET.fromstring (activelegs.text)

if len (Calllegs.findall ( " callLeg " )) < int (Calllegs.attrib [ " total " ] ):
offset = offset + ten
activelegs = requests.get (CMS_BASE + ' calls / ' + callid + '/ callLegs? offset = ' + str (Offset), verify = False . headers = CMS_HEADERS) activelegs.encoding = ' utf-8 '

calllegs.extend (ET.fromstring (activelegs.text) .findall ( " callLeg " ) )


return calllegs

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 47
Information about connecting to the conference call ID and known operations with them, for example - to be installed over the
specific screen configuration

def findlegs ():


offset = 0

activelegs = requests.get (CMS_BASE + ' calls / ' + callid + '/ callLegs' . verify = False . headers = CMS_HEADERS) activelegs.encoding = ' utf-8 '

calllegs = re.findall ( r'callLeg id = "(\ w + \ - \ w + \ - \ w + \ - \ w + \ - \ w +) ' . activelegs.text)


print (Calllegs)

one ed25b0e2b7d ',' e73cb349-1281-4f47-a9e2-b228dbedceb5 ','

f7749b16-6173-46b1-ab1d-4a85451269fc ',' bdac73d6-ec81-422abdb3-eadefb234353 ','


d7cebcb4-799f-4ef8-9090-
0373aa04-8c1f-40d0-8f9a-b5f78f98fa21 ']
c28d8918-c516-405f-a9db-382db87de3b0 ',' c45016cf-7812-4c9f-8b95-a0eb024ebc4c ','
af961c3b-e8e3-4daa-884d-89e29a32a4d8 ','b882fdf6-3d4c-46e7b3b6-9d0f0b87475f ','
80737b65-1385-463daa90-64a52f03e60f ',' aefb65b6 -6043-4603-b6a9-7cd0182095a2 ','
113ef87c-8925-4929-bf10-467649f53ed7 ',' 3105f6b5-d3ca-4c3b-9e6c-2e6159284fa4 ','
-8bf3786fca04 ',' 0e8d0458-0172-4a6abf3d-c26e8f0863b8 ','
0x1057dd188>, <Element' callLeg 'at 0x1057dd2c8>] [' 0d20279c-d792-4032-9206
0x1057d8ea8>, <Element' callLeg 'at 0x1057dd048>, <Element' callLeg 'at
0x1057cd5e8>, <Element
<Element 'callLegs' 'callLeg 'at 0x1057d8d68>, <Element' callLeg 'at
at 0x105666a48>
def findlegs ():
'callLeg' at 0x105675408>, <Element 'callLeg' at 0x105675638>, <Element 'callLeg' at
activelegs = requests.get (CMS_BASE + ' calls / ' + callid + '/ callLegs' . verify = False . headers = CMS_HEADERS) activelegs.encoding = ' utf-8 '
[<Element 'callLeg' at 0x10573b9a8>, <Element 'callLeg' at 0x105675728>, <Element

calllegs = ET.fromstring (activelegs.text) pprint


(calllegs)
all_legs = calllegs.findall ( " callLeg " )
pprint (all_legs)

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 48
Understanding the structure formed xml.etree.ElementTree
< callLegs total = " 14" > - 'Total' XML attribute upper level (calllegs.attrib)
< callLeg id = " 0 d20279c-d792-4032-9206-8bf3786fca04 " > - Attribute callLeg 'id' -
properties:
< name> </ name>
< remoteParty> 1000 @ str.ru </ RemoteParty> - remoteParty.text text
< call> 32 a41a3a-076d-4a25-b485-db9f1f1ea067 </ Call>
- Text (none)
</ callLeg> </
def printElement (element, shift = 0 ): # Function, the print elements of the XML structure shifttab = "\ t " * shift;
callLegs>
# shift of
print (Shifttab, " name: " . element.tag) # Name of the root element
print (Shifttab, " text: " . element.text) # The text of the root element
for attrname in element.keys (): # Print all the attributes of the root keys

print (Shifttab, " attr " . attrname, ":" , Element.attrib [attrname])

for subelement in element: # For each lower-level element


printElement (subelement, shift + one ) # Print it using this
name: callLegs text: None
# function, increasing Sdvizhkov

attr total: 14
name: callLeg text: None

attr id : 0 d20279c-d792-4032-9206-8bf3786fca04
name: name text: None

name: remoteParty text: 1000


@ str.ru
name: call text: 32 a41a3a-076d-4a25-b485-db9f1f1ea067

Cisco Connect 2017 © 2017 Cisco and / or its affiliates. All rights reserved. 49
Xpath syntax for xml.etree.ElementTree
Syntax performs
Selects all child elements of this tag. For example 'spam' selects all child elements named spam, and 'spam / egg' selects all child elements
tag
named egg child elements spam.
* Selects all child elements. For example, * / egg selects all child elements egg, all child elements.
. Selects the current level. The most useful at the beginning, to indicate levels, relative to the current

// Selects all podelementy at a level below the selected item. For example, .//egg selects all the elements in the tree.

.. Selects a parent element


[@Attrib] Selects all elements with these attributes
Selects all items in which said attribute is equal to the specified value. The value may not include single quotes.
[@ Attrib = 'value']

[Tag] Selects all elements that have a child with a name tag. Only works on one level.

[Tag = 'text'] Selects all elements that have a child is completely appropriate text field at all levels of nesting

Selects an item. 'Position' may be a number (1 - the first in the list), the expression last () (for the last element), or to set the relative level (i.e., last () -
[Position]
1). For example / callLegs / callLeg [2] - returns the second callLeg

calllegs = findlegs () print ( " Callleg ID: " + calllegs.find ( "./CallLeg[remoteParty='40220@demo.cisco.ru ']" ) .Attrib [ "Id" ])

print ( " Terminal Name " + calllegs.find ( "./ callLeg [remoteParty='40220@demo.cisco.ru '] / name " ). text) print ( " conference ID: " + calllegs.find
( "./ callLeg [remoteParty='40220@demo.cisco.ru '] / call " ). text) client.close ()

Callleg ID: 8646379f-fb0d-4dff-aae1-7ac02b65c59b


Terminal Name: SX20 Room - Moscow
conference ID: 32a41a3a-076d-4a25-b485-db9f1f1ea067
Open Source Resources

Canopy, Python SDK for Cisco CMS


https://github.com/gnisbetcisco/canopy

CDR receiver
https://github.com/jasonneurohr/acano_cdr_receiver
Cisco Meeting Server 2.x
development plans
Cisco Meeting Server version 2.2
Usability, flexibility and Maximum scalability Best in the industry
quality compatibility

New features Large quantity Support for multiple profiles


conferencing connections and load with quality and S4B
balancing O365

Scheduled for April - May 2017


Support for working with live video on two screens
Only possible with Cisco Collaboration solutions

• It allows you to display images of


participants on 2 screens

• Requires CMS 2.2 (May this year)

• Requires CE9.1 (this June)

• Supported on: SX80, MX800 Dual, MX700


Dual, Spark Kit, Spark Kit Plus
Cisco Meeting Server 2000
The best scalability in the industry

• At the start of the sales capacity of 500 HD


connections

• It requires a permit for importation


(pre-installed software, encryption of traffic -
built-in, not lockable key feature)
• High performance server based on UCS 5108 chassis and
B200 blades 6

• Fully configured chassis is sold as a single server

• GPL: 200,954 USD

• PID: CTI-CMS-2K-BUN-K9
Support O365 with OBTP
compatibility with no additional effort

• Planning conferences via Skype familiar to


users of Microsoft tools (Skype plugin)

• Cisco devices can use OBTP

• O365 customers can participate in the


dual-home conferences

• Requires TMS15.5 and XE5.5


Advanced features of the group Call Bridge
The best scalability in the industry

• Improve Scalability without deteriorating


the perceptual quality by cascading
multithreaded

• CMS 2.1 is only able to balance incoming


SIP connections

• CMS 2.2 adds a balancing mechanism


for outgoing SIP calls
Ability to set an "important" member
(Important Participant Pane Placement)
The best opportunities to work with Cisco Conferences

• Focuses the attention of participants on


important participants

• Ideal for lectures, speeches by leaders and other


conferences, where it is important to emphasize
certain windows

• It does not depend on the selected screen


layout

• Version 2.2 will be available through the CMS API.

• It is planned to add further levels of importance


and support to CMA / CMM
Other new features

• Ease of maintenance:
Simplify log collection process

• Pause for DTMF: Sending a delay determined


by the comma - ""

• connection quality:
Administrators will be able to capture the
quality of the connections on the SD, HD, full
HD, etc. to provide guaranteed quality for
users and more flexible management of
resources.
New Cisco
management
tools conferences
Cisco Meeting Manager
(White Glove Meeting Manger Tool)
A new tool for the operational management of conferences, standalone tool - no need

for TMS works will be delivered as a virtual machine, Web-based management

interface (Firefox, Chrome, Safari) Features planned in the first version:

A list of all active conferences, from which you can go to the selected conference management

List of all participants of the conference, mute the sound from one or all, turn off the party, complete
fault tolerance conference for CMM (active-active)
Appearance

• A single portal that integrates


various components

• Unified user interface (UX and


UI) and information architecture
(IA) with the Cisco cloud service
management portal.
The list of active conferences
conference system and its participants
Details of the connection of the conference participant
Development plans CMM

CMM 1.0 CMM 1.1 Future plans

• Control • Large Number of widgets • Provizhioning users and


Conference (Meeting Manager) PMP
• License monitor • Self-Service portal
• terminal management
• portal Administrator • CMS configuration
• Fine-tuning of conferences and
• basic widgets • Additional features conference
additional conferences
control management capabilities

TMS plans to continue to use for planning and other roles


# CiscoConnectRu

Thanks for attention!


Rate this session in a mobile application conference

www.facebook.com/CiscoRu
Contacts:
www.vk.com/cisco
Tel .: +7 495 9611410
www.instagram.com/ciscoru www.cisco.com

www.youtube.com/user/CiscoRussiaMedia

© 2017 Cisco and / or its affiliates. All rights reserved.

Das könnte Ihnen auch gefallen