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);
            }
        }
        TryAppendVertexXmlNode
        (
            String sUserName,
            XmlNode oEntryXmlNode,
            GraphMLXmlDocument oGraphMLXmlDocument,
            Dictionary <String, XmlNode> oUserNameDictionary
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(sUserName));
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(oUserNameDictionary != null);

            XmlNode oVertexXmlNode;

            if (oUserNameDictionary.TryGetValue(sUserName, out oVertexXmlNode))
            {
                return(false);
            }

            oVertexXmlNode = oGraphMLXmlDocument.AppendVertexXmlNode(sUserName);
            oUserNameDictionary.Add(sUserName, oVertexXmlNode);

            oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode,
                                                            NodeXLGraphMLUtil.VertexMenuTextID,
                                                            "Open YouTube Page for This Person");

            oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode,
                                                            NodeXLGraphMLUtil.VertexMenuActionID,
                                                            String.Format(WebPageUrlPattern, sUserName));

            return(true);
        }
        AppendDoubleGraphMLAttributeValue
        (
            XmlNode oXmlNodeToSelectFrom,
            String sXPath,
            XmlNamespaceManager oXmlNamespaceManager,
            GraphMLXmlDocument oGraphMLXmlDocument,
            XmlNode oEdgeOrVertexXmlNode,
            String sGraphMLAttributeID
        )
        {
            Debug.Assert(oXmlNodeToSelectFrom != null);
            Debug.Assert(!String.IsNullOrEmpty(sXPath));
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(oEdgeOrVertexXmlNode != null);
            Debug.Assert(!String.IsNullOrEmpty(sGraphMLAttributeID));
            AssertValid();

            Double dAttributeValue;

            if (XmlUtil2.TrySelectSingleNodeAsDouble(oXmlNodeToSelectFrom, sXPath,
                                                     oXmlNamespaceManager, out dAttributeValue))
            {
                oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                    oEdgeOrVertexXmlNode, sGraphMLAttributeID, dAttributeValue);

                return(true);
            }

            return(false);
        }
        AppendSampleThumbnails
        (
            Dictionary <String, XmlNode> oTagDictionary,
            GraphMLXmlDocument oGraphMLXmlDocument,
            String sApiKey,
            RequestStatistics oRequestStatistics
        )
        {
            Debug.Assert(oTagDictionary != null);
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(!String.IsNullOrEmpty(sApiKey));
            Debug.Assert(oRequestStatistics != null);
            AssertValid();

            foreach (KeyValuePair <String, XmlNode> oKeyValuePair in oTagDictionary)
            {
                String sTag = oKeyValuePair.Key;

                ReportProgress("Getting sample image file for \"" + sTag + "\".");

                String sSampleImageUrl;

                if (TryGetSampleImageUrl(sTag, sApiKey, oRequestStatistics,
                                         out sSampleImageUrl))
                {
                    oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                        oKeyValuePair.Value, NodeXLGraphMLUtil.VertexImageFileID,
                        sSampleImageUrl);
                }
            }
        }
Beispiel #5
0
        AppendValueFromValueDictionary
        (
            Dictionary <String, Object> valueDictionary,
            String name,
            GraphMLXmlDocument graphMLXmlDocument,
            XmlNode edgeOrVertexXmlNode,
            String graphMLAttributeID
        )
        {
            Debug.Assert(valueDictionary != null);
            Debug.Assert(!String.IsNullOrEmpty(name));
            Debug.Assert(graphMLXmlDocument != null);
            Debug.Assert(edgeOrVertexXmlNode != null);
            Debug.Assert(!String.IsNullOrEmpty(graphMLAttributeID));

            String value;

            if (TwitterJsonUtil.TryGetJsonValueFromDictionary(
                    valueDictionary, name, out value))
            {
                graphMLXmlDocument.AppendGraphMLAttributeValue(
                    edgeOrVertexXmlNode, graphMLAttributeID, value);

                return(true);
            }

            return(false);
        }
    AppendYouTubeDateGraphMLAttributeValue
    (
        XmlNode oXmlNodeToSelectFrom,
        String sXPath,
        XmlNamespaceManager oXmlNamespaceManager,
        GraphMLXmlDocument oGraphMLXmlDocument,
        XmlNode oVertexXmlNode,
        String sGraphMLAttributeID
    )
    {
        Debug.Assert(oXmlNodeToSelectFrom != null);
        Debug.Assert( !String.IsNullOrEmpty(sXPath) );
        Debug.Assert(oGraphMLXmlDocument != null);
        Debug.Assert(oVertexXmlNode != null);
        Debug.Assert( !String.IsNullOrEmpty(sGraphMLAttributeID) );
        AssertValid();

        String sYouTubeDate;

        if ( XmlUtil2.TrySelectSingleNodeAsString(oXmlNodeToSelectFrom,
            sXPath, oXmlNamespaceManager, out sYouTubeDate) )
        {
            oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode,
                sGraphMLAttributeID, FormatYouTubeDate(sYouTubeDate) );

            return (true);
        }

        return (false);
    }
Beispiel #7
0
        AppendGraphMLAttributeValues
        (
            IMetadataProvider oEdgeOrVertex,
            GraphMLXmlDocument oGraphMLXmlDocument,
            XmlNode oEdgeOrVertexXmlNode,
            String [] asAttributeNames,
            String AttributeIDPrefix
        )
        {
            Debug.Assert(oEdgeOrVertex != null);
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(oEdgeOrVertexXmlNode != null);
            Debug.Assert(asAttributeNames != null);
            Debug.Assert(!String.IsNullOrEmpty(AttributeIDPrefix));
            AssertValid();

            foreach (String sAttributeName in asAttributeNames)
            {
                Object oAttributeValue;

                // Note that the value type isn't checked.  Whatever type it is,
                // it gets converted to a string.

                if (oEdgeOrVertex.TryGetValue(sAttributeName,
                                              out oAttributeValue) && oAttributeValue != null)
                {
                    oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                        oEdgeOrVertexXmlNode, AttributeIDPrefix + sAttributeName,
                        oAttributeValue.ToString());
                }
            }
        }
Beispiel #8
0
        AppendUserStatisticsFromValueDictionary
        (
            Dictionary <String, Object> userValueDictionary,
            GraphMLXmlDocument graphMLXmlDocument,
            TwitterUser twitterUser
        )
        {
            Debug.Assert(userValueDictionary != null);
            Debug.Assert(graphMLXmlDocument != null);
            Debug.Assert(twitterUser != null);

            XmlNode vertexXmlNode = twitterUser.VertexXmlNode;

            AppendValueFromValueDictionary(userValueDictionary,
                                           "friends_count", graphMLXmlDocument, vertexXmlNode,
                                           VertexFollowedID);

            AppendValueFromValueDictionary(userValueDictionary,
                                           "followers_count", graphMLXmlDocument, vertexXmlNode,
                                           VertexFollowersID);

            AppendValueFromValueDictionary(userValueDictionary,
                                           "statuses_count", graphMLXmlDocument, vertexXmlNode,
                                           VertexStatusesID);

            AppendValueFromValueDictionary(userValueDictionary,
                                           "favourites_count", graphMLXmlDocument, vertexXmlNode,
                                           VertexFavoritesID);

            AppendValueFromValueDictionary(userValueDictionary,
                                           "description", graphMLXmlDocument, vertexXmlNode,
                                           VertexDescriptionID);

            AppendValueFromValueDictionary(userValueDictionary,
                                           "location", graphMLXmlDocument, vertexXmlNode,
                                           VertexLocationID);

            AppendValueFromValueDictionary(userValueDictionary,
                                           "url", graphMLXmlDocument, vertexXmlNode,
                                           VertexUrlID);

            AppendValueFromValueDictionary(userValueDictionary,
                                           "time_zone", graphMLXmlDocument, vertexXmlNode,
                                           VertexTimeZoneID);

            AppendValueFromValueDictionary(userValueDictionary,
                                           "utc_offset", graphMLXmlDocument, vertexXmlNode,
                                           VertexUtcOffsetID);

            String joinedDateUtc;

            if (TwitterJsonUtil.TryGetJsonValueFromDictionary(userValueDictionary,
                                                              "created_at", out joinedDateUtc))
            {
                graphMLXmlDocument.AppendGraphMLAttributeValue(
                    vertexXmlNode, VertexJoinedDateUtcID,
                    TwitterDateParser.ParseTwitterDate(joinedDateUtc));
            }
        }
        AppendEdgesFromDictionary
        (
            Dictionary <String, LinkedList <String> > oDictionary,
            GraphMLXmlDocument oGraphMLXmlDocument,
            String sRelationship,
            String sKeyAttributeID
        )
        {
            Debug.Assert(oDictionary != null);
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(!String.IsNullOrEmpty(sRelationship));
            Debug.Assert(!String.IsNullOrEmpty(sKeyAttributeID));
            AssertValid();

            // For each key...

            foreach (KeyValuePair <String, LinkedList <String> > oKeyValuePair in
                     oDictionary)
            {
                String sKey = oKeyValuePair.Key;

                // For each video ID that has the key...

                LinkedList <String> oVideoIDsWithThisKey = oKeyValuePair.Value;

                for (
                    LinkedListNode <String> oVideoIDWithThisKey =
                        oVideoIDsWithThisKey.First;

                    oVideoIDWithThisKey != null;

                    oVideoIDWithThisKey = oVideoIDWithThisKey.Next
                    )
                {
                    // For each of the subsequent video IDs in the LinkedList that
                    // have the key...

                    for (
                        LinkedListNode <String> oSubsequentVideoIDWithThisKey =
                            oVideoIDWithThisKey.Next;

                        oSubsequentVideoIDWithThisKey != null;

                        oSubsequentVideoIDWithThisKey =
                            oSubsequentVideoIDWithThisKey.Next
                        )
                    {
                        XmlNode oEdgeXmlNode = NodeXLGraphMLUtil.AppendEdgeXmlNode(
                            oGraphMLXmlDocument, oVideoIDWithThisKey.Value,
                            oSubsequentVideoIDWithThisKey.Value, sRelationship);

                        oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                            oEdgeXmlNode, sKeyAttributeID, sKey);
                    }
                }
            }
        }
Beispiel #10
0
        TryAppendVertexXmlNode
        (
            String screenName,
            String userID,
            GraphMLXmlDocument graphMLXmlDocument,
            Dictionary <String, TwitterUser> userIDDictionary,
            out TwitterUser twitterUser
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(screenName));
            Debug.Assert(!String.IsNullOrEmpty(userID));
            Debug.Assert(graphMLXmlDocument != null);
            Debug.Assert(userIDDictionary != null);

            twitterUser = null;

            if (userIDDictionary.TryGetValue(userID, out twitterUser))
            {
                // A vertex XML node already exists.

                return(false);
            }

            XmlNode vertexXmlNode = graphMLXmlDocument.AppendVertexXmlNode(
                screenName);

            twitterUser = new TwitterUser(screenName, vertexXmlNode);
            userIDDictionary.Add(userID, twitterUser);

            graphMLXmlDocument.AppendGraphMLAttributeValue(vertexXmlNode,
                                                           NodeXLGraphMLUtil.VertexMenuTextID,
                                                           "Open Twitter Page for This Person");

            graphMLXmlDocument.AppendGraphMLAttributeValue(
                vertexXmlNode,
                NodeXLGraphMLUtil.VertexMenuActionID,
                String.Format(TwitterApiUrls.UserWebPageUrlPattern, screenName)
                );

            return(true);
        }
Beispiel #11
0
        AppendLatitudeAndLongitudeGraphMLAttributeValues
        (
            GraphMLXmlDocument graphMLXmlDocument,
            XmlNode edgeOrVertexXmlNode,
            String latitude,
            String longitude
        )
        {
            Debug.Assert(graphMLXmlDocument != null);
            Debug.Assert(edgeOrVertexXmlNode != null);

            if (!String.IsNullOrEmpty(latitude))
            {
                graphMLXmlDocument.AppendGraphMLAttributeValue(
                    edgeOrVertexXmlNode, LatitudeID, latitude);
            }

            if (!String.IsNullOrEmpty(longitude))
            {
                graphMLXmlDocument.AppendGraphMLAttributeValue(
                    edgeOrVertexXmlNode, LongitudeID, longitude);
            }
        }
        AppendTweetedSearchTermGraphMLAttributeValue
        (
            GraphMLXmlDocument graphMLXmlDocument,
            TwitterUser twitterUser,
            Boolean userTweetedSearchTerm
        )
        {
            Debug.Assert(graphMLXmlDocument != null);
            Debug.Assert(twitterUser != null);

            graphMLXmlDocument.AppendGraphMLAttributeValue(
                twitterUser.VertexXmlNode,
                VertexTweetedSearchTermID,
                userTweetedSearchTerm ? "Yes" : "No");
        }
        AppendStartTimeRelationshipDateUtcGraphMLAttributeValue
        (
            GraphMLXmlDocument oGraphMLXmlDocument,
            XmlNode oEdgeXmlNode,
            RequestStatistics oRequestStatistics
        )
        {
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(oEdgeXmlNode != null);
            Debug.Assert(oRequestStatistics != null);
            AssertValid();

            oGraphMLXmlDocument.AppendGraphMLAttributeValue(oEdgeXmlNode,

                                                            TwitterGraphMLUtil.EdgeRelationshipDateUtcID,

                                                            DateTimeUtil2.ToCultureInvariantString(
                                                                oRequestStatistics.StartTimeUtc)
                                                            );
        }
        AppendEdgeXmlNode
        (
            GraphMLXmlDocument graphMLXmlDocument,
            String vertex1ID,
            String vertex2ID,
            String relationship
        )
        {
            Debug.Assert(graphMLXmlDocument != null);
            Debug.Assert(!String.IsNullOrEmpty(vertex1ID));
            Debug.Assert(!String.IsNullOrEmpty(vertex2ID));
            Debug.Assert(!String.IsNullOrEmpty(relationship));

            XmlNode edgeXmlNode = graphMLXmlDocument.AppendEdgeXmlNode(
                vertex1ID, vertex2ID);

            graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode,
                                                           EdgeRelationshipID, relationship);

            return(edgeXmlNode);
        }
Beispiel #15
0
        AppendInReplyToStatusIDGraphMLAttributeValue
        (
            GraphMLXmlDocument graphMLXmlDocument,
            XmlNode edgeOrVertexXmlNode,
            String inReplyToStatusID
        )
        {
            Debug.Assert(graphMLXmlDocument != null);
            Debug.Assert(edgeOrVertexXmlNode != null);

            if (!String.IsNullOrEmpty(inReplyToStatusID))
            {
                // Precede the ID with a single quote to force Excel to treat the
                // ID as text.  Otherwise, it formats the ID, which is a large
                // number, in scientific notation.

                graphMLXmlDocument.AppendGraphMLAttributeValue(
                    edgeOrVertexXmlNode, InReplyToStatusIDID,
                    "'" + inReplyToStatusID);
            }
        }
        AppendEdgeXmlNode
        (
            GraphMLXmlDocument oGraphMLXmlDocument,
            String sVertex1ID,
            String sVertex2ID,
            String sRelationship
        )
        {
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(!String.IsNullOrEmpty(sVertex1ID));
            Debug.Assert(!String.IsNullOrEmpty(sVertex2ID));
            Debug.Assert(!String.IsNullOrEmpty(sRelationship));
            AssertValid();

            XmlNode oEdgeXmlNode = oGraphMLXmlDocument.AppendEdgeXmlNode(
                sVertex1ID, sVertex2ID);

            oGraphMLXmlDocument.AppendGraphMLAttributeValue(oEdgeXmlNode,
                                                            RelationshipID, sRelationship);

            return(oEdgeXmlNode);
        }
        AppendVertexTooltipXmlNodes
        (
            GraphMLXmlDocument graphMLXmlDocument,
            Dictionary <String, TwitterUser> userIDDictionary
        )
        {
            Debug.Assert(graphMLXmlDocument != null);
            Debug.Assert(userIDDictionary != null);

            foreach (TwitterUser twitterUser in userIDDictionary.Values)
            {
                // The tooltip is the user's screen name followed by the first
                // tweet returned by Twitter.

                ICollection <TwitterStatus> statuses = twitterUser.Statuses;

                String firstStatus = statuses.Count > 0 ?
                                     statuses.First().Text : String.Empty;

                // The Excel template doesn't wrap long tooltip text.  Break the
                // status into lines so the entire tooltip will show in the graph
                // pane.

                firstStatus = StringUtil.BreakIntoLines(firstStatus, 30);

                String toolTip = String.Format(
                    "{0}\n\n{1}"
                    ,
                    twitterUser.ScreenName,
                    firstStatus
                    );

                graphMLXmlDocument.AppendGraphMLAttributeValue(
                    twitterUser.VertexXmlNode, VertexToolTipID, toolTip);
            }
        }
Beispiel #18
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);
                        }
                    }
                }
            }
        }
Beispiel #19
0
        AppendRepliesToAndMentionsEdgeXmlNode
        (
            GraphMLXmlDocument graphMLXmlDocument,
            String screenName1,
            String screenName2,
            String relationship,
            TwitterStatus twitterStatus
        )
        {
            Debug.Assert(graphMLXmlDocument != null);
            Debug.Assert(!String.IsNullOrEmpty(screenName1));
            Debug.Assert(!String.IsNullOrEmpty(screenName2));
            Debug.Assert(!String.IsNullOrEmpty(relationship));
            Debug.Assert(twitterStatus != null);

            XmlNode edgeXmlNode = NodeXLGraphMLUtil.AppendEdgeXmlNode(
                graphMLXmlDocument, screenName1, screenName2, relationship);

            String  statusDateUtc    = twitterStatus.ParsedDateUtc;
            Boolean hasStatusDateUtc = !String.IsNullOrEmpty(statusDateUtc);

            if (hasStatusDateUtc)
            {
                // The status's date is the relationship date.

                graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode,
                                                               EdgeRelationshipDateUtcID, statusDateUtc);
            }

            String statusText = twitterStatus.Text;

            graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode,
                                                           EdgeStatusID, statusText);

            String urls = twitterStatus.Urls;

            if (!String.IsNullOrEmpty(urls))
            {
                graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode,
                                                               EdgeStatusUrlsID, urls);

                graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode,
                                                               EdgeStatusDomainsID, UrlsToDomains(urls));
            }

            if (!String.IsNullOrEmpty(twitterStatus.Hashtags))
            {
                graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode,
                                                               EdgeStatusHashtagsID, twitterStatus.Hashtags);
            }

            if (hasStatusDateUtc)
            {
                graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode,
                                                               EdgeStatusDateUtcID, statusDateUtc);
            }

            graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode,
                                                           EdgeStatusWebPageUrlID,

                                                           FormatStatusWebPageUrl(screenName1, twitterStatus)
                                                           );

            AppendLatitudeAndLongitudeGraphMLAttributeValues(
                graphMLXmlDocument, edgeXmlNode, twitterStatus.Latitude,
                twitterStatus.Longitude);

            // Precede the ID with a single quote to force Excel to treat the
            // ID as text.  Otherwise, it formats the ID, which is a large
            // number, in scientific notation.

            graphMLXmlDocument.AppendGraphMLAttributeValue(edgeXmlNode,
                                                           NodeXLGraphMLUtil.ImportedIDID, "'" + twitterStatus.ID);

            AppendInReplyToStatusIDGraphMLAttributeValue(graphMLXmlDocument,
                                                         edgeXmlNode, twitterStatus.InReplyToStatusID);
        }
        AppendLatestStatusInformationFromValueDictionary
        (
            Dictionary <String, Object> oStatusValueDictionary,
            GraphMLXmlDocument oGraphMLXmlDocument,
            TwitterUser oTwitterUser,
            Boolean bIncludeLatestStatus,
            Boolean bExpandLatestStatusUrls
        )
        {
            Debug.Assert(oStatusValueDictionary != null);
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(oTwitterUser != null);
            AssertValid();

            TwitterStatus oTwitterStatus;

            if (!TwitterStatus.TryFromStatusValueDictionary(
                    oStatusValueDictionary, bExpandLatestStatusUrls,
                    out oTwitterStatus))
            {
                return;
            }

            XmlNode oVertexXmlNode = oTwitterUser.VertexXmlNode;

            if (bIncludeLatestStatus)
            {
                // Add the status to the vertex XML node.

                oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                    oVertexXmlNode, TwitterGraphMLUtil.VertexLatestStatusID,
                    oTwitterStatus.Text);

                String sLatestStatusUrls = oTwitterStatus.Urls;

                if (!String.IsNullOrEmpty(sLatestStatusUrls))
                {
                    oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                        oVertexXmlNode,
                        TwitterGraphMLUtil.VertexLatestStatusUrlsID,
                        sLatestStatusUrls);

                    oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                        oVertexXmlNode,
                        TwitterGraphMLUtil.VertexLatestStatusDomainsID,
                        TwitterGraphMLUtil.UrlsToDomains(sLatestStatusUrls));
                }

                String sLatestStatusHashtags = oTwitterStatus.Hashtags;

                if (!String.IsNullOrEmpty(sLatestStatusHashtags))
                {
                    oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                        oVertexXmlNode,
                        TwitterGraphMLUtil.VertexLatestStatusHashtagsID,
                        sLatestStatusHashtags);
                }

                if (!String.IsNullOrEmpty(oTwitterStatus.ParsedDateUtc))
                {
                    oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                        oVertexXmlNode,
                        TwitterGraphMLUtil.VertexLatestStatusDateUtcID,
                        oTwitterStatus.ParsedDateUtc);
                }

                TwitterGraphMLUtil.
                AppendLatitudeAndLongitudeGraphMLAttributeValues(
                    oGraphMLXmlDocument, oVertexXmlNode,
                    oTwitterStatus.Latitude, oTwitterStatus.Longitude);

                TwitterGraphMLUtil.AppendInReplyToStatusIDGraphMLAttributeValue(
                    oGraphMLXmlDocument, oVertexXmlNode,
                    oTwitterStatus.InReplyToStatusID);
            }

            oTwitterUser.Statuses.Add(oTwitterStatus);
        }
        AppendVertexXmlNodes
        (
            String sSearchTerm,
            WhatToInclude eWhatToInclude,
            Int32 iMaximumVideos,
            GraphMLXmlDocument oGraphMLXmlDocument,
            RequestStatistics oRequestStatistics,
            out HashSet <String> oVideoIDs,
            out Dictionary <String, LinkedList <String> > oCategoryDictionary
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(sSearchTerm));
            Debug.Assert(iMaximumVideos > 0);
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(oRequestStatistics != null);
            AssertValid();

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

            // This is used to skip duplicate videos in the results returned by
            // YouTube.  (I'm not sure why YouTube sometimes returns duplicates,
            // but it does.)

            oVideoIDs = new HashSet <String>();

            // If an edge should be included for each pair of videos that share the
            // same category, the key is a lower-case category and the value is a
            // LinkedList of the video IDs that have the category.

            if (WhatToIncludeFlagIsSet(eWhatToInclude,
                                       WhatToInclude.SharedCategoryEdges))
            {
                oCategoryDictionary =
                    new Dictionary <String, LinkedList <String> >();
            }
            else
            {
                oCategoryDictionary = null;
            }

            String sUrl = String.Format(

                "http://gdata.youtube.com/feeds/api/videos?q={0}"
                ,
                EncodeUrlParameter(sSearchTerm)
                );

            // The document consists of an "entry" XML node for each video.

            foreach (XmlNode oEntryXmlNode in EnumerateXmlNodes(sUrl,
                                                                "a:feed/a:entry", iMaximumVideos, false, oRequestStatistics))
            {
                XmlNamespaceManager oXmlNamespaceManager =
                    CreateXmlNamespaceManager(oEntryXmlNode.OwnerDocument);

                // Use the video ID as the GraphML vertex name.  The video title
                // can't be used because it is not unique.

                String sVideoID;

                if (
                    !XmlUtil2.TrySelectSingleNodeAsString(oEntryXmlNode,
                                                          "media:group/yt:videoid/text()", oXmlNamespaceManager,
                                                          out sVideoID)
                    ||
                    oVideoIDs.Contains(sVideoID)
                    )
                {
                    continue;
                }

                oVideoIDs.Add(sVideoID);

                XmlNode oVertexXmlNode = oGraphMLXmlDocument.AppendVertexXmlNode(
                    sVideoID);

                AppendStringGraphMLAttributeValue(oEntryXmlNode,
                                                  "a:title/text()", oXmlNamespaceManager, oGraphMLXmlDocument,
                                                  oVertexXmlNode, TitleID);

                AppendStringGraphMLAttributeValue(oEntryXmlNode,
                                                  "a:author/a:name/text()", oXmlNamespaceManager,
                                                  oGraphMLXmlDocument, oVertexXmlNode, AuthorID);

                AppendDoubleGraphMLAttributeValue(oEntryXmlNode,
                                                  "gd:rating/@average", oXmlNamespaceManager,
                                                  oGraphMLXmlDocument, oVertexXmlNode, RatingID);

                AppendInt32GraphMLAttributeValue(oEntryXmlNode,
                                                 "yt:statistics/@viewCount", oXmlNamespaceManager,
                                                 oGraphMLXmlDocument, oVertexXmlNode, ViewsID);

                AppendInt32GraphMLAttributeValue(oEntryXmlNode,
                                                 "yt:statistics/@favoriteCount", oXmlNamespaceManager,
                                                 oGraphMLXmlDocument, oVertexXmlNode, FavoritedID);

                AppendInt32GraphMLAttributeValue(oEntryXmlNode,
                                                 "gd:comments/gd:feedLink/@countHint", oXmlNamespaceManager,
                                                 oGraphMLXmlDocument, oVertexXmlNode, CommentsID);

                AppendYouTubeDateGraphMLAttributeValue(oEntryXmlNode,
                                                       "a:published/text()", oXmlNamespaceManager,
                                                       oGraphMLXmlDocument, oVertexXmlNode, CreatedDateUtcID);

                AppendStringGraphMLAttributeValue(oEntryXmlNode,
                                                  "media:group/media:thumbnail/@url", oXmlNamespaceManager,
                                                  oGraphMLXmlDocument, oVertexXmlNode,
                                                  NodeXLGraphMLUtil.VertexImageFileID);

                if (AppendStringGraphMLAttributeValue(oEntryXmlNode,
                                                      "media:group/media:player/@url", oXmlNamespaceManager,
                                                      oGraphMLXmlDocument, oVertexXmlNode,
                                                      NodeXLGraphMLUtil.VertexMenuActionID))
                {
                    oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode,
                                                                    NodeXLGraphMLUtil.VertexMenuTextID,
                                                                    "Play Video in Browser");
                }

                if (oCategoryDictionary != null)
                {
                    CollectCategories(oEntryXmlNode, sVideoID,
                                      oXmlNamespaceManager, oCategoryDictionary);
                }
            }
        }
Beispiel #22
0
        AppendUserInformationGraphMLAttributeValues
        (
            String sUserID,
            XmlNode oVertexXmlNode,
            GraphMLXmlDocument oGraphMLXmlDocument,
            String sApiKey,
            RequestStatistics oRequestStatistics
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(sUserID));
            Debug.Assert(oVertexXmlNode != null);
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(!String.IsNullOrEmpty(sApiKey));
            Debug.Assert(oRequestStatistics != null);
            AssertValid();

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

            XmlDocument oXmlDocument;

            if (!TryGetXmlDocument(sUrl, oRequestStatistics, out oXmlDocument))
            {
                // Ignore errors.  The user information isn't critical.

                return;
            }

            const String XPathRoot = "rsp/person/";

            AppendStringGraphMLAttributeValue(oXmlDocument,
                                              XPathRoot + "realname/text()", null, oGraphMLXmlDocument,
                                              oVertexXmlNode, RealNameID);

            AppendInt32GraphMLAttributeValue(oXmlDocument,
                                             XPathRoot + "photos/count/text()", null, oGraphMLXmlDocument,
                                             oVertexXmlNode, TotalPhotosID);

            String sIsProfessional;

            if (XmlUtil2.TrySelectSingleNodeAsString(oXmlDocument,
                                                     XPathRoot + "@ispro", null, out sIsProfessional))
            {
                oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode,
                                                                IsProfessionalID,
                                                                (sIsProfessional == "0") ? "No" : "Yes"
                                                                );
            }

            // Get the URL to the user's buddy icon, which is explained here:
            //
            // http://www.flickr.com/services/api/misc.buddyicons.html

            Int32  iIconServer, iIconFarm;
            String sBuddyIconUrl;

            if (
                XmlUtil2.TrySelectSingleNodeAsInt32(oXmlDocument,
                                                    XPathRoot + "@iconserver", null, out iIconServer)
                &&
                XmlUtil2.TrySelectSingleNodeAsInt32(oXmlDocument,
                                                    XPathRoot + "@iconfarm", null, out iIconFarm)
                &&
                iIconServer > 0
                )
            {
                sBuddyIconUrl = String.Format(

                    "http://farm{0}.static.flickr.com/{1}/buddyicons/{2}.jpg"
                    ,
                    iIconFarm,
                    iIconServer,
                    sUserID
                    );
            }
            else
            {
                sBuddyIconUrl = "http://www.flickr.com/images/buddyicon.jpg";
            }

            oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                oVertexXmlNode, ImageFileID, sBuddyIconUrl);

            if (AppendStringGraphMLAttributeValue(oXmlDocument,
                                                  XPathRoot + "photosurl/text()", null, oGraphMLXmlDocument,
                                                  oVertexXmlNode, MenuActionID))
            {
                oGraphMLXmlDocument.AppendGraphMLAttributeValue(oVertexXmlNode,
                                                                MenuTextID, "Open Flickr Page for This Person");
            }
        }
Beispiel #23
0
        GetUserNetworkRecursive
        (
            String sUserID,
            String sScreenName,
            WhatToInclude eWhatToInclude,
            Boolean bIncludeContactsThisCall,
            NetworkLevel eNetworkLevel,
            Int32 iMaximumPerRequest,
            String sApiKey,
            Int32 iRecursionLevel,
            GraphMLXmlDocument oGraphMLXmlDocument,
            Dictionary <String, XmlNode> oUserIDDictionary,
            RequestStatistics oRequestStatistics
        )
        {
            Debug.Assert(!String.IsNullOrEmpty(sUserID));
            Debug.Assert(!String.IsNullOrEmpty(sScreenName));

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

            Debug.Assert(iMaximumPerRequest > 0);
            Debug.Assert(!String.IsNullOrEmpty(sApiKey));
            Debug.Assert(iRecursionLevel == 1 || iRecursionLevel == 2);
            Debug.Assert(oGraphMLXmlDocument != null);
            Debug.Assert(oUserIDDictionary != 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);

            List <String> oUserIDsToRecurse = new List <String>();

            ReportProgressForContactsOrCommenters(sScreenName,
                                                  bIncludeContactsThisCall);

            Boolean bThisUserAppended = false;

            foreach (XmlNode oChildXmlNode in GetContactsOrCommentersEnumerator(
                         sUserID, bIncludeContactsThisCall, iMaximumPerRequest,
                         oGraphMLXmlDocument, sApiKey, oRequestStatistics))
            {
                String sOtherScreenName, sOtherUserID;

                if (
                    !XmlUtil2.TrySelectSingleNodeAsString(oChildXmlNode,
                                                          bIncludeContactsThisCall ? "@username" : "@authorname",
                                                          null, out sOtherScreenName)
                    ||
                    !XmlUtil2.TrySelectSingleNodeAsString(oChildXmlNode,
                                                          bIncludeContactsThisCall ? "@nsid" : "@author",
                                                          null, out sOtherUserID)
                    )
                {
                    continue;
                }

                if (!bThisUserAppended)
                {
                    // Append a vertex node for this request's user.
                    //
                    // This used to be done after the foreach loop, which avoided
                    // the need for a "bThisUserAppended" flag.  That caused the
                    // following bug: If a YouTube error occurred within
                    // EnumerateXmlNodes() after some edges had been added, and the
                    // user decided to import the resulting partial network, the
                    // GraphML might contain edges that referenced "this user"
                    // without containing a vertex for "this user."  That is an
                    // illegal state for GraphML, which the ExcelTemplate project
                    // caught and reported as an error.

                    TryAppendVertexXmlNode(sUserID, sScreenName,
                                           oGraphMLXmlDocument, oUserIDDictionary);

                    bThisUserAppended = true;
                }

                if (bNeedToAppendVertices)
                {
                    if (
                        TryAppendVertexXmlNode(sOtherUserID, sOtherScreenName,
                                               oGraphMLXmlDocument, oUserIDDictionary)
                        &&
                        bNeedToRecurse
                        )
                    {
                        oUserIDsToRecurse.Add(sOtherUserID);
                    }
                }

                if (bNeedToAppendVertices ||
                    oUserIDDictionary.ContainsKey(sOtherUserID))
                {
                    // Append an edge node and optional attributes.

                    XmlNode oEdgeXmlNode;

                    if (bIncludeContactsThisCall)
                    {
                        oEdgeXmlNode = AppendEdgeXmlNode(oGraphMLXmlDocument,
                                                         sScreenName, sOtherScreenName, "Contact");
                    }
                    else
                    {
                        // (Note the swapping of screen names in the commenter
                        // case.)

                        oEdgeXmlNode = AppendEdgeXmlNode(oGraphMLXmlDocument,
                                                         sOtherScreenName, sScreenName, "Commenter");

                        UInt32 uCommentDateUtc;

                        if (XmlUtil2.TrySelectSingleNodeAsUInt32(oChildXmlNode,
                                                                 "@datecreate", null, out uCommentDateUtc))
                        {
                            DateTime oCommentDateUtc =
                                DateTimeUtil2.UnixTimestampToDateTimeUtc(
                                    uCommentDateUtc);

                            oGraphMLXmlDocument.AppendGraphMLAttributeValue(
                                oEdgeXmlNode, CommentDateUtcID,

                                ExcelDateTimeUtil.DateTimeToStringLocale1033(
                                    oCommentDateUtc, ExcelColumnFormat.DateAndTime)
                                );
                        }

                        AppendStringGraphMLAttributeValue(oChildXmlNode,
                                                          "@permalink", null, oGraphMLXmlDocument, oEdgeXmlNode,
                                                          CommentUrlID);
                    }
                }
            }

            if (bNeedToRecurse)
            {
                foreach (String sUserIDToRecurse in oUserIDsToRecurse)
                {
                    XmlNode oVertexXmlNode = oUserIDDictionary[sUserIDToRecurse];

                    String sScreenNameToRecurse = GetScreenNameFromVertexXmlNode(
                        oVertexXmlNode);

                    GetUserNetworkRecursive(sUserIDToRecurse, sScreenNameToRecurse,
                                            eWhatToInclude, bIncludeContactsThisCall, eNetworkLevel,
                                            iMaximumPerRequest, sApiKey, 2, oGraphMLXmlDocument,
                                            oUserIDDictionary, oRequestStatistics);
                }
            }
        }