/// <summary>
        /// Performs log-in procedure
        /// </summary>
        /// <param name="userName">valid Adobe Connect acount name</param>
        /// <param name="userPassword">valid Adobe Connect acount password</param>
        /// <param name="iStatus">after succesfull login, <see cref="StatusInfo">iStatus</see> contains session ID to be used for single-sign-on.</param>
        /// <returns><see cref="bool"/></returns>
        public bool Login(string userName, string userPassword, out StatusInfo iStatus)
        {
            //action=login&[email protected]&password=football&session=
            //cookie: BREEZESESSION

            iStatus = new StatusInfo();

            try
            {
                //StatusInfo iStatus;
                XmlDocument xDoc = _ProcessRequest("login", string.Format("login={0}&password={1}", userName, userPassword), true, out iStatus);
                if (xDoc == null || !xDoc.HasChildNodes) return false;
                //return (xDoc.SelectSingleNode("//status/@code").Value.Equals("ok")) ? true : false;
                return (iStatus.Code == StatusCodes.ok) ? true : false;
            }
            catch (Exception ex)
            {
                TraceTool.TraceException(ex);
            }
            return false;
        }
        /// <summary>
        /// Returns a list of SCOs within another SCO. The enclosing SCO can be a folder, meeting, or
        /// curriculum.
        /// </summary>
        /// <param name="sco_id">Room/Folder ID</param>
        /// <param name="iStatus"></param>
        /// <returns>Raw contents as <see cref="XmlNodeList"/></returns>
        public XmlNodeList GetMeetingsInRoomRaw(string sco_id, out StatusInfo iStatus)
        {
            iStatus = new StatusInfo();
            XmlDocument xDoc = _ProcessRequest("sco-contents", string.Format("sco-id={0}", sco_id), out iStatus);
            if (iStatus.Code != StatusCodes.ok || xDoc == null || !xDoc.HasChildNodes) return null;

            XmlNodeList transNodes = xDoc.SelectNodes("//sco");
            if (transNodes == null || transNodes.Count < 1) return null;

            return transNodes;
        }
        /// <summary>
        /// Method is intented to retrive data from AC 'Content' folder. E.g.: Quizzes
        /// </summary>
        /// <returns>Raw contents as <see cref="XmlNodeList"/></returns>
        public XmlNodeList GetQuizzesInRoom(string sco_id, out StatusInfo iStatus)
        {
            iStatus = new StatusInfo();
            XmlDocument xDoc = _ProcessRequest("sco-contents", string.Format("sco-id={0}", sco_id), out iStatus);
            if (iStatus.Code != StatusCodes.ok || xDoc == null || !xDoc.HasChildNodes) return null;

            XmlNodeList MeetingDetailNodes = xDoc.SelectNodes("//sco");
            if (MeetingDetailNodes == null || MeetingDetailNodes.Count < 1)
            {
                iStatus = ReportStatus(StatusCodes.no_data, StatusSubCodes.not_set, new ArgumentNullException("Node 'sco' is empty"));
                return null;
            }
            else
            {
                return MeetingDetailNodes;
            }
        }
        private XmlDocument _ProcessRequest(string pAction, string qParams, bool extractSessionCookie, out StatusInfo iStatus)
        {
            iStatus = new StatusInfo();
            iStatus.Code = StatusCodes.not_set;

            if (qParams == null) qParams = string.Empty;

            HttpWebRequest HttpWReq = WebRequest.Create(m_serviceURL + string.Format(@"?action={0}&{1}", pAction, qParams)) as HttpWebRequest;
            if (HttpWReq == null) return null;

            try
            {
                if (!string.IsNullOrEmpty(this.m_proxyUrl))
                {
                    if (!string.IsNullOrEmpty(this.m_netUser) && !string.IsNullOrEmpty(this.m_netPassword))
                    {
                        HttpWReq.Proxy = new System.Net.WebProxy(this.m_proxyUrl, true);
                        HttpWReq.Proxy.Credentials = new NetworkCredential(this.m_netUser, this.m_netPassword, this.m_netDomain);
                    }

                }
            }
            catch (Exception ex)
            {
                TraceTool.TraceException(ex);
            }

            //20 sec. timeout: A Domain Name System (DNS) query may take up to 15 seconds to return or time out.
            HttpWReq.Timeout = 20000 * 60;
            HttpWReq.Accept = "*/*";
            HttpWReq.KeepAlive = false;
            HttpWReq.CookieContainer = new CookieContainer();

            if ((!m_sessionParam) && (!extractSessionCookie))
            {
                if (!string.IsNullOrEmpty(m_SessionInfo) && !string.IsNullOrEmpty(m_SessionDomain))
                    HttpWReq.CookieContainer.Add(new System.Net.Cookie("BREEZESESSION", this.m_SessionInfo, "/", this.m_SessionDomain));
            }

            HttpWebResponse HttpWResp = null;

            try
            {
                //FIX: invalid SSL passing behavior
                //(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
                ServicePointManager.ServerCertificateValidationCallback = delegate
                {
                    return true;
                };

                HttpWResp = HttpWReq.GetResponse() as HttpWebResponse;

                if (extractSessionCookie)
                {
                    if (HttpWResp.Cookies["BREEZESESSION"] != null)
                    {
                        this.m_SessionInfo = HttpWResp.Cookies["BREEZESESSION"].Value;
                        this.m_SessionDomain = HttpWResp.Cookies["BREEZESESSION"].Domain;
                        iStatus.SessionInfo = this.m_SessionInfo;
                    }
                }

                Stream receiveStream = HttpWResp.GetResponseStream();
                if (receiveStream == null) return null;

                XmlDocument xDoc = null;
                using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
                {
                    string buf = readStream.ReadToEnd();
                    if (!string.IsNullOrEmpty(buf))
                    {
                        xDoc = new XmlDocument();
                        xDoc.Load(new StringReader(buf));

                        iStatus.InnerXml = xDoc.InnerXml;

                        object var = this.ReflectEnum(typeof(StatusCodes), xDoc.SelectSingleNode("//status/@code").Value);
                        if (var != null)
                            iStatus.Code = (StatusCodes)var;

                        switch (iStatus.Code)
                        {
                            case StatusCodes.invalid:
                                //there is not always an invalid child element
                                XmlNode node = xDoc.SelectSingleNode("//invalid");
                                if (node != null)
                                {
                                    iStatus.SubCode = (StatusSubCodes)this.ReflectEnum(typeof(StatusSubCodes), node.Attributes["subcode"].Value);
                                    iStatus.InvalidField = node.Attributes["field"].Value;
                                }
                                break;
                            case StatusCodes.no_access:
                                iStatus.SubCode = (StatusSubCodes)this.ReflectEnum(typeof(StatusSubCodes), xDoc.SelectSingleNode("//status/@subcode").Value);
                                break;
                            default: break;
                        }
                    }
                }

                return xDoc;
            }
            catch (Exception ex)
            {
                HttpWReq.Abort();
                TraceTool.TraceException(ex);
                iStatus.UndeliningExceptionInfo = ex;
            }
            finally
            {
                if (HttpWResp != null)
                    HttpWResp.Close();
            }

            return null;
        }
        /// <summary>
        /// Returns a list of SCOs within another SCO. The enclosing SCO can be a folder, meeting, or
        /// curriculum.
        /// In general, the contained SCOs can be of any type—meetings, courses, curriculums, content,
        /// events, folders, trees, or links (see the list in type). However, the type of the contained SCO
        /// needs to be valid for the enclosing SCO. For example, courses are contained within
        /// curriculums, and meeting content is contained within meetings.
        /// Because folders are SCOs, the returned list includes SCOs and subfolders at the next
        /// hierarchical level, but not the contents of the subfolders. To include the subfolder contents,
        /// call sco-expanded-contents.
        /// </summary>
        /// <param name="sco_id">Room/Folder ID</param>
        /// <param name="iStatus">status response object returned</param>
        /// <returns><see cref="MeetingItem">MeetingItem</see> array</returns>
        public MeetingItem[] GetMeetingsInRoom(string sco_id, out StatusInfo iStatus)
        {
            //act: "sco-contents"

            iStatus = new StatusInfo();
            XmlDocument xDoc = _ProcessRequest("sco-contents", string.Format("sco-id={0}", sco_id), out iStatus);
            if (iStatus.Code != StatusCodes.ok || xDoc == null || !xDoc.HasChildNodes) return null;

            XmlNodeList MeetingDetailNodes = xDoc.SelectNodes("//sco");
            if (MeetingDetailNodes == null || MeetingDetailNodes.Count < 1)
            {
                //iStatus = ReportStatus(StatusCodes.no_data, StatusSubCodes.not_set, new ArgumentNullException("Node 'sco' is empty"));
                TraceTool.TraceMessage("Node 'sco' is empty: no data available for sco-id=" + sco_id);
                return null;
            }

            List<MeetingItem> lstDetails = new List<MeetingItem>();
            foreach (XmlNode node in MeetingDetailNodes)
            {
                try
                {
                    MeetingItem mDetail = new MeetingItem();
                    mDetail.sco_id = node.Attributes["sco-id"].Value;
                    mDetail.folder_id = node.Attributes["folder-id"].Value;
                    if (!bool.TryParse(node.Attributes["is-folder"].Value, out mDetail.is_folder))
                        mDetail.is_folder = false;
                    if (node.Attributes["byte-count"] != null)
                        if (!long.TryParse(node.Attributes["byte-count"].Value, NumberStyles.Number, NumberFormatInfo.InvariantInfo, out mDetail.byte_count))
                            mDetail.byte_count = -1;
                    if (node.Attributes["lang"] != null)
                        mDetail.language = node.Attributes["lang"].Value;
                    if (node.Attributes["type"] != null)
                        mDetail.type = (SCOtype)ReflectEnum(typeof(SCOtype), node.Attributes["type"].Value);

                    if (node.SelectSingleNode("name/text()") != null)
                        mDetail.meeting_name = node.SelectSingleNode("name/text()").Value;
                    if (node.SelectSingleNode("description/text()") != null)
                        mDetail.meeting_description = node.SelectSingleNode("description/text()").Value;

                    if (node.SelectSingleNode("sco-tag/text()") != null)
                        mDetail.sco_tag = node.SelectSingleNode("sco-tag/text()").Value;

                    mDetail.url_path = node.SelectSingleNode("url-path/text()").Value;
                    //
                    if (!string.IsNullOrEmpty(mDetail.url_path))
                    {
                        Uri u = new Uri(m_serviceURL);
                        mDetail.FullUrl = "https://" + u.GetComponents(UriComponents.Host, UriFormat.SafeUnescaped) + mDetail.url_path;
                    }

                    //NOTE: if folder =>  date-begin is null
                    if (node.SelectSingleNode("date-begin/text()") != null)
                        if (!DateTime.TryParseExact(node.SelectSingleNode("date-begin/text()").Value, @"yyyy-MM-dd\THH:mm:ss.fffzzz", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AdjustToUniversal, out mDetail.date_begin))
                            mDetail.date_begin = default(DateTime);

                    if (!DateTime.TryParseExact(node.SelectSingleNode("date-modified/text()").Value, @"yyyy-MM-dd\THH:mm:ss.fffzzz", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AdjustToUniversal, out mDetail.date_modified))
                        mDetail.date_modified = default(DateTime);

                    if (node.SelectSingleNode("date-end/text()") != null)
                        if (!DateTime.TryParseExact(node.SelectSingleNode("date-end/text()").Value, @"yyyy-MM-dd\THH:mm:ss.fffzzz", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AdjustToUniversal, out mDetail.date_end))
                            mDetail.date_end = default(DateTime);

                    mDetail.Duration = mDetail.date_end.Subtract(mDetail.date_begin);

                    //if mDetail.date_begin is not defined and duration is 0 => then this is the folder which should be ignored
                    if (mDetail.date_begin.Equals(default(DateTime)) && mDetail.Duration.TotalMinutes == 0) continue;

                    lstDetails.Add(mDetail);

                }
                catch (Exception ex)
                {
                    TraceTool.TraceException(ex);
                }

            }

            return lstDetails.ToArray();
        }
 private XmlDocument _ProcessRequest(string pAction, string qParams, out StatusInfo iStatus)
 {
     //Single sign on (SSO) implementation can be done via passing session info information as ""?session=" parameter to the Adobe Connect event url.
     if (m_sessionParam)
     {
         if (String.IsNullOrEmpty(qParams))
         {
             qParams = "session=" + m_SessionInfo;
         }
         else
         {
             qParams = String.Concat("session=", m_SessionInfo, @"&", qParams);
         }
     }
     return this._ProcessRequest(pAction, qParams, false, out iStatus);
 }
 StatusInfo ReportStatus(StatusCodes code, StatusSubCodes subCode, Exception exInfo)
 {
     StatusInfo iStatus = new StatusInfo();
     iStatus.Code = code;
     iStatus.SubCode = subCode;
     iStatus.UndeliningExceptionInfo = exInfo;
     return iStatus;
 }
        /// <summary>
        /// Provides information about all users who have taken a quiz in a training. Use a sco-id to
        /// identify the quiz.
        /// To reduce the volume of the response, use any allowed filter or pass a type parameter to
        /// return information about just one type of SCO (courses, presentations, or meetings).
        /// </summary>
        /// <returns>Raw contents as <see cref="XmlNodeList"/></returns>
        public XmlNodeList Report_QuizTakers(string sco_id, string filter_by, out StatusInfo iStatus)
        {
            XmlDocument xDoc = _ProcessRequest("report-quiz-takers", string.Format("sco-id={0}&{1}", sco_id, filter_by), out iStatus);
            if (iStatus.Code != StatusCodes.ok || xDoc == null || !xDoc.HasChildNodes) return null;

            XmlNodeList transNodes = xDoc.SelectNodes("//row");
            if (transNodes == null || transNodes.Count < 1) return null;

            return transNodes;
        }
        /// <summary>
        /// Returns information about principal-to-SCO transactions on your server or in your hosted account.
        /// A transaction is an instance of one principal visiting one SCO. The SCO can be an Acrobat
        /// Connect Professional meeting, course, document, or any content on the server.
        /// Note: this call to report-bulk-consolidated-transactions, with filter-type=meeting, returns only
        /// users who logged in to the meeting as participants, not users who entered the meeting as guests.
        /// </summary>
        /// <returns><see cref="TransactionInfo">TransactionInfo</see> array</returns>
        public TransactionInfo[] Report_ConsolidatedTransactions(string filter_by, out StatusInfo iStatus)
        {
            XmlDocument xDoc = _ProcessRequest("report-bulk-consolidated-transactions", filter_by, out iStatus);
            if (iStatus.Code != StatusCodes.ok || xDoc == null || !xDoc.HasChildNodes) return null;

            XmlNodeList transNodes = xDoc.SelectNodes("//row");
            if (transNodes == null || transNodes.Count < 1) return null;

            List<TransactionInfo> tInfoList = new List<TransactionInfo>();
            foreach (XmlNode node in transNodes)
            {
                TransactionInfo ti = new TransactionInfo();

                try
                {
                    ti.transaction_id = node.Attributes["transaction-id"].Value;
                    ti.sco_id = node.Attributes["sco-id"].Value;
                    ti.principal_id = node.Attributes["principal-id"].Value;
                    if (node.Attributes["type"] != null)
                        ti.type = (SCOtype)ReflectEnum(typeof(SCOtype), node.Attributes["type"].Value);
                    ti.score = node.Attributes["score"].Value;

                    ti.name = node.SelectSingleNode("name/text()").Value;
                    ti.url = node.SelectSingleNode("url/text()").Value;
                    ti.login = node.SelectSingleNode("login/text()").Value;
                    ti.user_name = node.SelectSingleNode("user-name/text()").Value;
                    if (node.SelectSingleNode("status/text()") != null)
                    {
                        ti.status = node.SelectSingleNode("status/text()").Value;
                        //ti.status = (StatusCodes)ReflectEnum(typeof(StatusCodes), node.SelectSingleNode("status/text()").Value);
                    }

                    if (!DateTime.TryParseExact(node.SelectSingleNode("date-created/text()").Value, @"yyyy-MM-dd\THH:mm:ss.fffzzz", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AdjustToUniversal, out ti.date_created))
                        ti.date_created = default(DateTime);

                    if (!DateTime.TryParseExact(node.SelectSingleNode("date-closed/text()").Value, @"yyyy-MM-dd\THH:mm:ss.fffzzz", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AdjustToUniversal, out ti.date_closed))
                        ti.date_closed = default(DateTime);

                    tInfoList.Add(ti);

                }
                catch (Exception ex)
                {
                    TraceTool.TraceException(ex);
                }

            }

            return tInfoList.ToArray();
        }
示例#10
0
        /// <summary>
        /// Returns bulk questions information
        /// </summary>
        /// <param name="filter_by">optional 'filter by' params</param> 
        /// <param name="iStatus">status response object returned</param>
        /// <returns>Raw contents as <see cref="XmlNodeList"/></returns>
        public XmlNodeList Report_BulkQuestions(string filter_by, out StatusInfo iStatus)
        {
            XmlDocument xDoc = _ProcessRequest("report-bulk-questions", string.Format("{0}", filter_by), out iStatus);
            if (iStatus.Code != StatusCodes.ok || xDoc == null || !xDoc.HasChildNodes) return null;

            XmlNodeList transNodes = xDoc.SelectNodes("//row");
            if (transNodes == null || transNodes.Count < 1) return null;

            return transNodes;
        }