public void CreateTrafficStructure(AFElement repoElement)
        {
            if (!repoElement.Elements.Contains("Traffic"))
            {
                var traffic        = repoElement.Elements.Add("Traffic", repoElement.Database.ElementTemplates["Traffic"]);
                var referrers      = traffic.Elements.Add("Referrers", repoElement.Database.ElementTemplates["Referrers"]);
                var popularContent = traffic.Elements.Add("PopularContents", repoElement.Database.ElementTemplates["PopularContents"]);

                // Popular content is a fixed number, there is always only 10
                for (int i = 1; i < 11; i++)
                {
                    popularContent.Elements.Add(string.Format("Popular-{0:00}", i), repoElement.Database.ElementTemplates["PopularContent"]);
                }

                repoElement.CheckIn();
                GitHubCommon.CreateTags(repoElement);
            }
        }
        public override List <AFValue> ReadValues(AFElement orgElement)
        {
            var settings = GitHubCommon.GetAFSettings(orgElement);
            var github   = GitHubCommon.GetGitHubClient(settings);

            if (GitHubCommon.isGitHubRateLimitExceeded(github))
            {
                return(new List <AFValue>());
            }


            // Read repositories from GitHub
            var repos = github.Repository.GetAllForOrg(settings.GitHubOwner).Result;

            var values = new List <AFValue>();

            // for each repository, we create it if it does not exist and we retrieve repo values in AF
            foreach (var repo in repos)
            {
                var targetRepoElement = GitHubCommon.FindRepositoryById(orgElement, settings, repo.Id.ToString());

                AFElement repoElement;
                if (targetRepoElement.Count == 0)
                {
                    // create new repo element
                    repoElement = new AFElement(repo.Name, settings.RepositoryTemplate);
                    orgElement.Elements.Add(repoElement);
                    orgElement.CheckIn();

                    GitHubCommon.CreateTags(repoElement);
                }

                else
                {
                    // update
                    repoElement = targetRepoElement[0];
                }


                // if name has changed, we rename the element, we keep track of the repository by ids, so we can do that
                // it makes the AF structure easier to navigate
                if (repoElement.Name != repo.Name)
                {
                    repoElement.Name = repo.Name;
                }

                // pull requests
                var pullRequests      = github.PullRequest.GetAllForRepository(repo.Owner.Login, repo.Name);
                var pullRequestsCount = pullRequests.Result.Count;

                // commits
                var contributors      = github.Repository.Statistics.GetContributors(repo.Owner.Login, repo.Name);
                var contributorsCount = contributors.Result.Count;
                var totalCommits      = contributors.Result.ToList().Sum(contributor => contributor.Total);


                //Create AFValues based on the GitHub Readings
                values.AddRange(new List <AFValue>()
                {
                    new AFValue(repoElement.Attributes["Repository Id"], repo.Id, AFTime.Now),
                    new AFValue(repoElement.Attributes["Commits"], totalCommits, AFTime.Now),
                    new AFValue(repoElement.Attributes["Contributors"], contributorsCount, AFTime.Now),
                    new AFValue(repoElement.Attributes["Forks"], repo.ForksCount, AFTime.Now),
                    new AFValue(repoElement.Attributes["Name"], repo.Name, AFTime.Now),
                    new AFValue(repoElement.Attributes["Pull Requests"], pullRequestsCount, AFTime.Now),
                    new AFValue(repoElement.Attributes["Stars"], repo.StargazersCount, AFTime.Now),
                    new AFValue(repoElement.Attributes["Url"], repo.HtmlUrl, AFTime.Now),
                    new AFValue(repoElement.Attributes["UpdatedAt"], repo.UpdatedAt.LocalDateTime, AFTime.Now),
                    new AFValue(repoElement.Attributes["HasDownloads"], repo.HasDownloads, AFTime.Now),
                    new AFValue(repoElement.Attributes["HasIssues"], repo.HasIssues, AFTime.Now),
                    new AFValue(repoElement.Attributes["Open Issues"], repo.OpenIssuesCount, AFTime.Now),
                    new AFValue(repoElement.Attributes["HasWiki"], repo.HasWiki, AFTime.Now),
                    new AFValue(repoElement.Attributes["Watchers"], github.Activity.Watching.GetAllWatchers(settings.GitHubOwner, repo.Name).Result.Count, AFTime.Now),
                }
                                );
                if (AFSDKHelpers.GetAttributeValue <DateTime>(repoElement, "CreatedAt") <= new DateTime(1970, 1, 1))
                {
                    values.Add(new AFValue(repoElement.Attributes["CreatedAt"], repo.CreatedAt.LocalDateTime, AFTime.Now));
                }
            }

            var rateLimits = github.Miscellaneous.GetRateLimits().Result.Resources;

            Logger.InfoFormat("GitHub rate limits: Search:{0}, Core: {1}", rateLimits.Search.Remaining, rateLimits.Core.Remaining);

            return(values);
        }
        public override List <AFValue> ReadValues(AFElement orgElement)
        {
            var values   = new List <AFValue>();
            var settings = GitHubCommon.GetAFSettings(orgElement);
            var github   = GitHubCommon.GetGitHubClient(settings);

            if (GitHubCommon.isGitHubRateLimitExceeded(github))
            {
                return(values);
            }


            // Read repositories from GitHub
            var repos = github.Repository.GetAllForOrg(settings.GitHubOwner).Result;


            foreach (var repo in repos)
            {
                var targetRepoElement = GitHubCommon.FindRepositoryById(orgElement, settings, repo.Id.ToString());

                AFElement repoElement;

                // check if the repo exists in the AF structure
                if (targetRepoElement.Count == 0)
                {
                    Logger.InfoFormat("{0} Repository does not exist in AF.  Traffic data will not be collected.", repo.Name);
                }

                else
                {
                    // repo exists
                    repoElement = targetRepoElement[0];

                    // create the af structure if it does not exist
                    CreateTrafficStructure(repoElement);

                    //traffic
                    // traffic - clones and views
                    var traffic = repoElement.Elements["Traffic"];

                    var clonesTask = github.Repository.Traffic.GetClones(repo.Id, new RepositoryTrafficRequest(TrafficDayOrWeek.Day));
                    var viewsTask  = github.Repository.Traffic.GetViews(repo.Id, new RepositoryTrafficRequest(TrafficDayOrWeek.Day));

                    Task.WaitAll(clonesTask, viewsTask);

                    foreach (var clone in clonesTask.Result.Clones)
                    {
                        values.Add(new AFValue(traffic.Attributes["clones-uniques"], clone.Uniques, clone.Timestamp.DateTime));
                        values.Add(new AFValue(traffic.Attributes["clones-count"], clone.Count, clone.Timestamp.DateTime));
                    }


                    foreach (var view in viewsTask.Result.Views)
                    {
                        values.Add(new AFValue(traffic.Attributes["views-uniques"], view.Uniques, view.Timestamp.DateTime));
                        values.Add(new AFValue(traffic.Attributes["views-count"], view.Count, view.Timestamp.DateTime));
                    }



                    // referrers
                    var refElem   = repoElement.Elements["Traffic"].Elements["Referrers"];
                    var referrers = github.Repository.Traffic.GetReferrers(repo.Id).Result;
                    foreach (var referrer in referrers)
                    {
                        AFElement refererElem;
                        if (!refElem.Elements.Contains(referrer.Referrer))
                        {
                            refererElem = refElem.Elements.Add(referrer.Referrer, repoElement.Database.ElementTemplates["Referrer"]);
                            refererElem.CheckIn();
                            GitHubCommon.CreateTags(refererElem);
                        }
                        else
                        {
                            refererElem = refElem.Elements[referrer.Referrer];
                        }


                        //Create AFValues based on the GitHub Readings
                        values.AddRange(new List <AFValue>()
                        {
                            new AFValue(refererElem.Attributes["count"], referrer.Count, AFTime.Now),
                            new AFValue(refererElem.Attributes["uniques"], referrer.Uniques, AFTime.Now)
                        }
                                        );
                    }

                    // popular
                    var popularElems = repoElement.Elements["Traffic"].Elements["PopularContents"];
                    var popContents  = github.Repository.Traffic.GetPaths(repo.Id).Result;
                    for (int i = 0; i < popContents.Count; i++)
                    {
                        var popContent  = popContents[i];
                        var popularElem = popularElems.Elements[i];

                        //Create AFValues based on the GitHub Readings
                        values.AddRange(new List <AFValue>()
                        {
                            new AFValue(popularElem.Attributes["count"], popContent.Count, AFTime.Now),
                            new AFValue(popularElem.Attributes["uniques"], popContent.Uniques, AFTime.Now),
                            new AFValue(popularElem.Attributes["path"], popContent.Path, AFTime.Now),
                            new AFValue(popularElem.Attributes["title"], popContent.Title, AFTime.Now)
                        }
                                        );
                    }
                }
            }

            return(values);
        }