Skip to content

Instantly share code, notes, and snippets.

@trevrosen
Created July 23, 2009 11:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trevrosen/152807 to your computer and use it in GitHub Desktop.
Save trevrosen/152807 to your computer and use it in GitHub Desktop.
module WebEx
## Convenience methods
def self.filter_by_session_name(collection, name=nil)
return collection unless name
collection.collect{|session|
session if session['sessionName'].downcase.include?(name)
}.compact
end
class XMLObject
attr_accessor :xml, :processor
def initialize(xml)
@xml = xml
end
class << self
# Creates an attendee for a meeting given the meeting's key.
def create_meeting_attendee(attendee, payload=nil)
raise ArgumentError, "Argument must be of type WebEx::Attendee" unless attendee.class == WebEx::Attendee
unless payload
payload = ""
xml = Builder::XmlMarkup.new(:target => payload)
xml.body {
xml.bodyContent('xsi:type' => "java:com.webex.service.binding.attendee.CreateMeetingAttendee"){
xml.sessionKey(attendee.session_key)
xml.joinStatus("ACCEPT")
xml.person{
xml.name(attendee.name)
xml.email(attendee.email)
}
}
}
end
# End xml
attendee_object = XMLObject.new(payload)
attendee_object.processor = Proc.new do |doc|
results_hash = Hash.new
doc.elements.each('//att:attendee') do |ele|
results_hash.merge!({ ele.name => ele.text })
end
results_hash
end
# End processor
attendee_object
end
# Delete a given attendee by ID
def delete_meeting_attendee(attendee_id, payload=nil)
unless payload
payload = ""
xml = Builder::XmlMarkup.new(:target => payload)
xml.body {
xml.bodyContent('xsi:type' => "java:com.webex.service.binding.attendee.DelMeetingAttendee"){
xml.attendeeID(attendee_id)
}
}
end
# End xml
attendee_object = XMLObject.new(payload)
attendee_object.processor = Proc.new do |doc|
results_hash = Hash.new
doc.elements.each('//serv:bodyContent') do |ele|
results_hash.merge!({ ele.name => ele.text })
end
results_hash
end
# End processor
attendee_object
end
# Given a meeting's session key, return the attendee list for that meeting.
def lst_meeting_attendee(session_key, payload=nil)
raise ArgumentError, "session_key must contain only digits" unless session_key =~ /^[\d]+$/
unless payload
payload = ""
xml = Builder::XmlMarkup.new(:target => payload)
xml.body {
xml.bodyContent('xsi:type' => "java:com.webex.service.binding.attendee.LstMeetingAttendee"){
xml.sessionKey(session_key)
}
}
end
# End xml
attendee_object = XMLObject.new(payload)
attendee_object.processor = Proc.new do |doc|
attendees = []
names = %w[com:name com:email att:sessionKey att:joinStatus att:contactID]
REXML::XPath.each(doc.root, '//att:attendee') do |attendee|
attendees << names.inject({}) do |hash, element_name|
element = attendee.elements.to_a(".//#{element_name}").first
hash[element_name.split(":").last] = (element ? element.text : nil)
hash
end
end
attendees
end
# End processor
attendee_object
end
# Attendee list for a meeting, including duration of attendance. If no session key, gives last 500 attendees.
def lst_event_attendee_history(session_key=nil, payload=nil)
if session_key
raise ArgumentError, "session_key must contain only digits" unless session_key =~ /^[\d]+$/
end
unless payload
payload = ""
xml = Builder::XmlMarkup.new(:target => payload)
xml.body {
xml.bodyContent('xsi:type' => "java:com.webex.service.binding.history.LsteventattendeeHistory"){
if session_key
xml.sessionKey(session_key)
end
xml.listControl{
xml.startFrom("1")
xml.maximumNum("500")
}
xml.order{
xml.orderBy("ATTENDEENAME")
xml.orderAD("ASC")
}
}
}
end
# End xml
attendee_object = XMLObject.new(payload)
attendee_object.processor = Proc.new do |doc|
attendees = []
names = %w[history:attendeeName history:attendeeEmail history:duration history:participantType history:meetingKey]
REXML::XPath.each(doc.root, '//history:eventAttendeeHistory') do |attendee|
attendees << names.inject({}) do |hash, element_name|
element = attendee.elements.to_a(".//#{element_name}").first
hash[element_name.split(":").last] = (element ? element.text : nil)
hash
end
end
attendees
end
# End processor
attendee_object
end
# List specific data for Events happening after a certain time. Defaults to Time.now.
def event_list(name=nil, time_limit=Time.now, payload=nil)
unless payload
payload = ""
xml = Builder::XmlMarkup.new(:target => payload)
xml.body {
xml.bodyContent('xsi:type' => "java:com.webex.service.binding.event.LstsummaryEvent"){
xml.listControl {
xml.startFrom('1')
xml.listMethod('OR')
}
xml.dateScope{
if time_limit
xml.startDateStart(WebEx.webex_time_string(time_limit))
end
xml.timeZoneID("11")
}
xml.order {
xml.orderBy('STARTTIME')
xml.orderAD('ASC')
}
}
}
end
# End xml
event_object = XMLObject.new(payload)
event_object.processor = Proc.new do |doc|
event_keys = %w[sessionKey status startDate endDate sessionName]
events = []
REXML::XPath.each(doc.root, "//event:event") do |event|
events << event_keys.inject({}) do |hash, event_key|
element = event.elements["event:#{event_key}"]
hash[event_key] = (element ? element.text : nil)
hash
end
end
WebEx.filter_by_session_name(events, name)
end
# End processor
event_object
end
# List specific data for Meetings happening after a certain time. Defaults to Time.now.
def meeting_list(time_limit=Time.now, payload=nil)
unless payload
xml = Builder::XmlMarkup.new(:target => payload)
xml.body {
xml.bodyContent('xsi:type' => "java:com.webex.service.binding.meeting.LstsummaryMeeting"){
xml.listControl {
xml.startFrom('1')
xml.maximumNum('10')
xml.listMethod('OR')
}
xml.order {
xml.orderBy('STARTTIME')
xml.orderAD('ASC')
}
}
}
end
# End xml
meeting_object = XMLObject.new(payload)
meeting_object.processor = Proc.new do |doc|
meeting_keys = %w[meetingKey startDate status confName]
meetings = []
REXML::XPath.each(doc.root, "//meet:meeting") do |meeting|
meetings << meeting_keys.inject({}) do |hash, meeting_key|
element = meeting.elements["meet:#{meeting_key}"]
hash[meeting_key] = (element ? element.text : nil)
hash
end
end
WebEx.filter_by_time(meetings, 'startDate', time_limit)
end
# End processor
meeting_object
end
# List specific data for all sessions (includes WebEx Events, Meetings, etc) happening after a certain time. Defaults to Time.now.
def session_list(time_limit=Time.now, payload=nil)
unless payload
payload = ""
xml = Builder::XmlMarkup.new(:target => payload)
xml.body {
xml.bodyContent('xsi:type' => "java:com.webex.service.binding.ep.LstsummarySession"){
xml.listControl {
xml.startFrom('1')
xml.maximumNum('10')
xml.listMethod('OR')
}
xml.dateScope{
if time_limit
xml.startDateStart(WebEx.webex_time_string(time_limit))
end
xml.timeZoneID("11")
}
xml.order {
xml.orderBy('STARTTIME')
xml.orderAD('ASC')
}
}
}
end
# End xml
session_object = XMLObject.new(payload)
session_object.processor = Proc.new do |doc|
session_keys = %w[sessionKey startTime status confName sessionType serviceType]
sessions = []
REXML::XPath.each(doc.root, "//ep:session") do |session|
sessions << session_keys.inject({}) do |hash, session_key|
element = session.elements["ep:#{session_key}"]
hash[session_key] = (element ? element.text : nil)
hash
end
end
WebEx.filter_by_time(sessions, 'startTime', time_limit)
end
# End processor
session_object
end
end
end
class Attendee
attr_accessor :name, :email, :session_key, :start_date
def initialize(name, email, session_key, start_date)
raise ArgumentError, 'session_key must contain only digits' unless session_key =~ /^[\d]+$/
raise ArgumentError, 'start_date must be of class Time' unless start_date.class == Time
@name, @email, @session_key, @start_date = name, email, session_key, start_date
end
# Add an attendee to the meeting identified by its session key
def add_to_meeting
w = WebEx::Request.new
w.send_request(XMLObject.create_meeting_attendee(self))
end
# Escape name for URL use
def url_name
self.name.gsub(" ", "%20")
end
# Escape email address for URL use
def url_email
self.email.gsub('@', '%40')
end
end
class Request
attr_accessor :doc, :response, :body
# Builds "security context" portion of XML body, calls request_post and parses result.
# Argument must be a WebEx::XMLObject.
def send_request(request_object)
return false unless request_object.xml && request_object.processor
payload = ""
xml = Builder::XmlMarkup.new(:target => payload)
xml.instruct!("xml", :version => "1.0", :encoding => "ISO-8859-1")
xml.tag!("serv:message", 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'){
xml.header{
xml.securityContext{
xml.webExID(WEBEX['ID']);
xml.password(WEBEX['PASSWORD']);
xml.siteID(WEBEX['SITE_ID']);
xml.partnerID(WEBEX['PARTNER_ID']);
}
}
xml << request_object.xml
}
self.doc = REXML::Document.new(self.request_post(WEBEX['CONNECTION_URL'], payload))
self.body = request_object.processor.call(self.doc)
return { :body => self.body, :response => self.response }
end
# Performs actual HTTP request and returns the request body.
def request_post(url, payload)
RestClient.post(url, payload)
end
# Holds response type ("SUCCESS" or "FAILURE") and exception code (if exists)
def response
@response ||= Proc.new{
response_hash = {}
self.doc.elements.each('//serv:header/serv:response/*') do |ele|
response_hash.merge!({ ele.name.to_sym => ele.text })
end
response_hash
}.call
end
private
# Enables easy calling of API request methods
def method_missing(request_method, *args)
self.send_request(WebEx::XMLObject.send(request_method.to_sym, *args))
end
end
# End Request class
end
# End WebEx module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment