Created
July 23, 2009 11:56
-
-
Save trevrosen/152807 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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