AppendVertexXmlNode
        (
            String sTag,
            GraphMLXmlDocument oGraphMLXmlDocument,
            Dictionary <String, XmlNode> oTagDictionary
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(sTag));
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(oTagDictionary != null);

            if (!oTagDictionary.ContainsKey(sTag))
            {
                XmlNode oVertexXmlNode = oGraphMLXmlDocument.AppendVertexXmlNode(
                    sTag);

                oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode,
                                                                NodeXLGraphMLUtil.VertexLabelID, sTag);

                oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode,
                                                                NodeXLGraphMLUtil.VertexMenuTextID,
                                                                "Open Flickr Page for This Tag");

                oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode,
                                                                NodeXLGraphMLUtil.VertexMenuActionID,

                                                                String.Format(
                                                                    "http://www.flickr.com/photos/tags/{0}/"
                                                                    ,
                                                                    UrlUtil.EncodeUrlParameter(sTag)
                                                                    ));

                oTagDictionary.Add(sTag, oVertexXmlNode);
            }
        }
    EncodeUrlParameter
    (
        String urlParameter
    )
    {
        Debug.Assert(urlParameter != null);

        // From the YouTube documentation:
        //
        // "To URL escape a string, convert each sequence of whitespace
        // characters to a single "+" (plus sign) and replace any other
        // nonalphanumeric characters with the hexadecimal encoding that
        // represents the value of that character."

        // Compress whitespace into a single space.

        urlParameter = Regex.Replace(urlParameter, "\\s+", " ");

        // Use .NET's URL encoding.

        urlParameter = UrlUtil.EncodeUrlParameter(urlParameter);

        // That converted each space to "%20".  Convert that to the plus sign
        // YouTube expects.

        urlParameter = urlParameter.Replace("%20", "+");

        return (urlParameter);
    }
Пример #3
0
        FlickrScreenNameToUserID
        (
            String sScreenNameAnyCase,
            String sApiKey,
            RequestStatistics oRequestStatistics,
            out String sUserID,
            out String sScreenNameCorrectCase
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(sScreenNameAnyCase));
            Debug.Assert(!String.IsNullOrEmpty(sApiKey));
            Debug.Assert(oRequestStatistics != null);
            AssertValid();

            XmlDocument oXmlDocument = GetXmlDocument(

                GetFlickrMethodUrl("flickr.people.findByUsername", sApiKey,
                                   "&username="******"rsp/user/@nsid", null);

            sScreenNameCorrectCase = XmlUtil2.SelectRequiredSingleNodeAsString(
                oXmlDocument, "rsp/user/username/text()", null);
        }
Пример #4
0
        GetCommentersEnumerator
        (
            String sUserID,
            Int32 iMaximumPerRequest,
            Boolean bSkipMostPage1Errors,
            String sApiKey,
            RequestStatistics oRequestStatistics
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(sUserID));
            Debug.Assert(iMaximumPerRequest > 0);
            Debug.Assert(!String.IsNullOrEmpty(sApiKey));
            Debug.Assert(oRequestStatistics != null);

            AssertValid();

            // Get the user's public photos, which are paged.

            String sUrl = GetFlickrMethodUrl("flickr.people.getPublicPhotos",
                                             sApiKey, GetUserIDUrlParameter(sUserID));

            foreach (XmlNode oPhotoXmlNode in EnumerateXmlNodes(sUrl,
                                                                "rsp/photos/photo", iMaximumPerRequest, bSkipMostPage1Errors,
                                                                oRequestStatistics))
            {
                String sPhotoID;

                if (!XmlUtil2.TrySelectSingleNodeAsString(oPhotoXmlNode, "@id",
                                                          null, out sPhotoID))
                {
                    continue;
                }

                // Get the photo's comments, which are not paged.

                ReportProgress(String.Format(

                                   "Getting comments for the photo \"{0}\"."
                                   ,
                                   sPhotoID
                                   ));

                sUrl = GetFlickrMethodUrl("flickr.photos.comments.getList",
                                          sApiKey, "&photo_id=" + UrlUtil.EncodeUrlParameter(sPhotoID)
                                          );

                XmlDocument oXmlDocument;

                if (TryGetXmlDocument(sUrl, oRequestStatistics,
                                      out oXmlDocument))
                {
                    foreach (XmlNode oCommentXmlNode in oXmlDocument.SelectNodes(
                                 "rsp/comments/comment"))
                    {
                        yield return(oCommentXmlNode);
                    }
                }
            }
        }
Пример #5
0
        GetUserIDUrlParameter
        (
            String sUserID
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(sUserID));
            AssertValid();

            return("&user_id=" + UrlUtil.EncodeUrlParameter(sUserID));
        }
        TryGetSampleImageUrl
        (
            String sTag,
            String sApiKey,
            RequestStatistics oRequestStatistics,
            out String sSampleImageUrl
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(sTag));
            Debug.Assert(!String.IsNullOrEmpty(sApiKey));
            Debug.Assert(oRequestStatistics != null);
            AssertValid();

            sSampleImageUrl = null;

            String sUrl = GetFlickrMethodUrl("flickr.tags.getClusterPhotos",
                                             sApiKey, "&tag=" + UrlUtil.EncodeUrlParameter(sTag));

            XmlDocument oXmlDocument;
            String      sPhotoID;

            if (
                !TryGetXmlDocument(sUrl, oRequestStatistics, out oXmlDocument)
                ||
                !XmlUtil2.TrySelectSingleNodeAsString(oXmlDocument,
                                                      "rsp/photos/photo/@id", null, out sPhotoID)
                )
            {
                return(false);
            }

            sUrl = GetFlickrMethodUrl("flickr.photos.getSizes", sApiKey,
                                      "&photo_id=" + UrlUtil.EncodeUrlParameter(sPhotoID));

            if (
                !TryGetXmlDocument(sUrl, oRequestStatistics, out oXmlDocument)
                ||
                !XmlUtil2.TrySelectSingleNodeAsString(oXmlDocument,
                                                      "rsp/sizes/size[@label='Thumbnail']/@source", null,
                                                      out sSampleImageUrl)
                )
            {
                return(false);
            }

            return(true);
        }
        GetRelatedTagsRecursive
        (
            String sTag,
            WhatToInclude eWhatToInclude,
            NetworkLevel eNetworkLevel,
            String sApiKey,
            Int32 iRecursionLevel,
            GraphMLXmlDocument oGraphMLXmlDocument,
            Dictionary <String, XmlNode> oTagDictionary,
            RequestStatistics oRequestStatistics
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(sTag));

            Debug.Assert(eNetworkLevel == NetworkLevel.One ||
                         eNetworkLevel == NetworkLevel.OnePointFive ||
                         eNetworkLevel == NetworkLevel.Two);

            Debug.Assert(!String.IsNullOrEmpty(sApiKey));
            Debug.Assert(iRecursionLevel == 1 || iRecursionLevel == 2);
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(oTagDictionary != null);
            Debug.Assert(oRequestStatistics != null);
            AssertValid();

            /*
             * Here is what this method should do, based on the eNetworkLevel and
             * iRecursionLevel parameters.
             *
             *      eNetworkLevel
             *
             |One               | OnePointFive      | Two
             *  ---|------------------| ------------------| -----------------
             * i   1  |Add all vertices. | Add all vertices. | Add all vertices.
             * R      |                  |                   |
             * e      |Add all edges.    | Add all edges.    | Add all edges.
             * c      |                  |                   |
             * u      |Do not recurse.   | Recurse.          | Recurse.
             * r      |                  |                   |
             * s   ---|------------------|-------------------|------------------
             * i   2  |Impossible.       | Do not add        | Add all vertices.
             * o      |                  | vertices.         |
             * n      |                  |                   |
             * L      |                  | Add edges only if | Add all edges.
             * e      |                  | vertices are      |
             * v      |                  | already included. |
             * e      |                  |                   |
             * l      |                  | Do not recurse.   | Do not recurse.
             |                  |                   |
             |  ---|------------------|-------------------|------------------
             */

            Boolean bNeedToRecurse = GetNeedToRecurse(eNetworkLevel,
                                                      iRecursionLevel);

            Boolean bNeedToAppendVertices = GetNeedToAppendVertices(
                eNetworkLevel, iRecursionLevel);

            ReportProgress("Getting tags related to \"" + sTag + "\".");

            String sUrl = GetFlickrMethodUrl("flickr.tags.getRelated", sApiKey,
                                             "&tag=" + UrlUtil.EncodeUrlParameter(sTag));

            XmlDocument oXmlDocument;

            try
            {
                oXmlDocument = GetXmlDocument(sUrl, oRequestStatistics);
            }
            catch (Exception oException)
            {
                // If the exception is not a WebException or XmlException, or if
                // none of the network has been obtained yet, throw the exception.

                if (!HttpSocialNetworkUtil.ExceptionIsWebOrXml(oException) ||
                    !oGraphMLXmlDocument.HasVertexXmlNode)
                {
                    throw oException;
                }

                return;
            }

            // The document consists of a single "tags" node with zero or more
            // "tag" child nodes.

            String sOtherTag = null;

            XmlNodeList oTagNodes = oXmlDocument.DocumentElement.SelectNodes(
                "tags/tag");

            if (oTagNodes.Count > 0)
            {
                AppendVertexXmlNode(sTag, oGraphMLXmlDocument, oTagDictionary);
            }

            foreach (XmlNode oTagNode in oTagNodes)
            {
                sOtherTag = XmlUtil2.SelectRequiredSingleNodeAsString(oTagNode,
                                                                      "text()", null);

                if (bNeedToAppendVertices)
                {
                    AppendVertexXmlNode(sOtherTag, oGraphMLXmlDocument,
                                        oTagDictionary);
                }

                if (bNeedToAppendVertices ||
                    oTagDictionary.ContainsKey(sOtherTag))
                {
                    oGraphMLXmlDocument.AppendEdgeXmlNode(sTag, sOtherTag);
                }
            }

            if (bNeedToRecurse)
            {
                foreach (XmlNode oTagNode in oTagNodes)
                {
                    sOtherTag = XmlUtil2.SelectRequiredSingleNodeAsString(oTagNode,
                                                                          "text()", null);

                    GetRelatedTagsRecursive(sOtherTag, eWhatToInclude,
                                            eNetworkLevel, sApiKey, 2, oGraphMLXmlDocument,
                                            oTagDictionary, oRequestStatistics);
                }
            }
        }
Пример #8
0
        AppendVertexXmlNodes
        (
            String sSearchTerm,
            WhatToInclude eWhatToInclude,
            Int32 iMaximumPeoplePerRequest,
            GraphMLXmlDocument oGraphMLXmlDocument,
            Dictionary <String, TwitterVertex> oScreenNameDictionary,
            RequestStatistics oRequestStatistics
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(sSearchTerm));
            Debug.Assert(iMaximumPeoplePerRequest > 0);
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(oScreenNameDictionary != null);
            Debug.Assert(oRequestStatistics != null);
            AssertValid();

            // Convert spaces in the search term to a plus sign.
            //
            // (Note: Don't try to use Twitter's "show_user" URL parameter in an
            // attempt to get a "user" XML node for each author.  That's not what
            // the URL parameter does.)

            String sUrl = String.Format(

                "http://search.twitter.com/search.atom?q={0}&rpp=100"
                ,
                UrlUtil.EncodeUrlParameter(sSearchTerm).Replace("%20", "+")
                );

            ReportProgress("Getting a list of tweets.");

            Boolean bIncludeStatistics = WhatToIncludeFlagIsSet(
                eWhatToInclude, WhatToInclude.Statistics);

            Boolean bIncludeStatuses = WhatToIncludeFlagIsSet(
                eWhatToInclude, WhatToInclude.Statuses);

            // The document consists of an "entry" XML node for each tweet that
            // contains the search term.  Multiple tweets may have the same author,
            // so we have to enumerate until the requested maximum number of unique
            // authors is reached.

            foreach (XmlNode oAuthorNameXmlNode in EnumerateXmlNodes(
                         sUrl, "a:feed/a:entry/a:author/a:name", "a", AtomNamespaceUri,
                         15, Int32.MaxValue, true, false, oRequestStatistics))
            {
                if (oScreenNameDictionary.Count == iMaximumPeoplePerRequest)
                {
                    break;
                }

                // The author name is in this format:
                //
                // james_laker (James Laker)

                String sAuthorName;

                if (!XmlUtil2.TrySelectSingleNodeAsString(oAuthorNameXmlNode,
                                                          "text()", null, out sAuthorName))
                {
                    continue;
                }

                Int32  iIndexOfSpace = sAuthorName.IndexOf(' ');
                String sScreenName   = sAuthorName;

                if (iIndexOfSpace != -1)
                {
                    sScreenName = sAuthorName.Substring(0, iIndexOfSpace);
                }

                sScreenName = sScreenName.ToLower();

                TwitterVertex oTwitterVertex;

                if (!TryAppendVertexXmlNode(sScreenName, null,
                                            oGraphMLXmlDocument, oScreenNameDictionary, bIncludeStatistics,
                                            false, out oTwitterVertex))
                {
                    // A tweet for the author has already been found.

                    continue;
                }

                XmlNode oVertexXmlNode = oTwitterVertex.VertexXmlNode;
                XmlNode oEntryXmlNode  = oAuthorNameXmlNode.ParentNode.ParentNode;

                XmlNamespaceManager oXmlNamespaceManager = new XmlNamespaceManager(
                    oEntryXmlNode.OwnerDocument.NameTable);

                oXmlNamespaceManager.AddNamespace("a", AtomNamespaceUri);

                // Get the image URL and status for the tweet's author.

                AppendStringGraphMLAttributeValue(oEntryXmlNode,
                                                  "a:link[@rel='image']/@href", oXmlNamespaceManager,
                                                  oGraphMLXmlDocument, oVertexXmlNode, ImageFileID);

                String sStatus;

                if (XmlUtil2.TrySelectSingleNodeAsString(oEntryXmlNode,
                                                         "a:title/text()", oXmlNamespaceManager, out sStatus))
                {
                    String sStatusDateUtc;

                    if (XmlUtil2.TrySelectSingleNodeAsString(oEntryXmlNode,
                                                             "a:published/text()", oXmlNamespaceManager,
                                                             out sStatusDateUtc))
                    {
                        sStatusDateUtc = TwitterDateParser.ParseTwitterDate(
                            sStatusDateUtc);
                    }

                    oTwitterVertex.StatusForAnalysis        = sStatus;
                    oTwitterVertex.StatusForAnalysisDateUtc = sStatusDateUtc;

                    if (bIncludeStatuses)
                    {
                        oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                            oVertexXmlNode, StatusID, sStatus);

                        if (!String.IsNullOrEmpty(sStatusDateUtc))
                        {
                            oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                                oVertexXmlNode, StatusDateUtcID, sStatusDateUtc);
                        }
                    }
                }
            }
        }