public AncestryDnaToolsViewModel() { var serializedMatchesReaders = new List <ISerializedMatchesReader> { new DnaGedcomAncestryMatchesReader(), new DnaGedcomFtdnaMatchesReader(), new SharedClusteringMatchesReader(), new AutoClusterCsvMatchesReader(), new AutoClusterExcelMatchesReader(), }; var matchesLoader = new MatchesLoader(serializedMatchesReaders); // Extendable list of tabs to display. var clusteringTab = new AncestryDnaHierarchicalClusteringViewModel(matchesLoader); Tabs = new List <object> { new IntroductionViewModel(), new AncestryDnaDownloadingViewModel(OpenInClusterTab), new AncestryDnaHierarchicalClusteringViewModel(matchesLoader), new AncestryDnaSimilarityViewModel(matchesLoader), }; SelectedTabIndex = Settings.Default.SelectedTabIndex; }
public AncestryDnaToolsViewModel() { // Ancestry's security works by setting some cookies in the browser when someone signs in. // The CookieContainer captures those cookies when they are set, and adds them to subsequent requests. var cookies = new CookieContainer(); var handler = new HttpClientHandler { CookieContainer = cookies }; var ancestryClient = new HttpClient(handler) { BaseAddress = new Uri("https://www.ancestry.com"), Timeout = TimeSpan.FromMinutes(5) }; var loginHelper = new AncestryLoginHelper(ancestryClient, cookies); var testsRetriever = new AncestryTestsRetriever(ancestryClient); var matchesRetriever = new AncestryMatchesRetriever(ancestryClient); var endogamyProber = new EndogamyProber(matchesRetriever); var serializedMatchesReaders = new List <ISerializedMatchesReader> { new DnaGedcomAncestryMatchesReader(), new DnaGedcomFtdnaMatchesReader(), new SharedClusteringMatchesReader(), new AutoClusterCsvMatchesReader(), new AutoClusterExcelMatchesReader(), }; var matchesLoader = new MatchesLoader(serializedMatchesReaders); var signInViewModel = new AncestryDnaSignInViewModel(loginHelper, testsRetriever); // Extendable list of tabs to display. var clusteringTab = new AncestryDnaHierarchicalClusteringViewModel(matchesLoader); Tabs = new List <object> { new IntroductionViewModel(), new AncestryDnaDownloadingViewModel(signInViewModel, matchesRetriever, endogamyProber, OpenInClusterTab), new AncestryDnaHierarchicalClusteringViewModel(matchesLoader), new AncestryDnaSimilarityViewModel(matchesLoader), new AncestryDnaExportViewModel(matchesLoader), new AncestryDnaUploadNotesViewModel(signInViewModel, new AncestryNotesUpdater(matchesRetriever)), }; SelectedTabIndex = Settings.Default.SelectedTabIndex; }
public async Task ExtendSavedDataAsync(string guid) { var serializedMatchesReaders = new List <ISerializedMatchesReader> { new DnaGedcomAncestryMatchesReader(), new DnaGedcomFtdnaMatchesReader(), new SharedClusteringMatchesReader(), new AutoClusterCsvMatchesReader(), new AutoClusterExcelMatchesReader(), }; var matchesLoader = new MatchesLoader(serializedMatchesReaders); Settings.Default.Save(); var startTime = DateTime.Now; var(testTakerTestId, clusterableMatches) = await matchesLoader.LoadClusterableMatchesAsync(@"C:\Users\JSB\Desktop\Ancestry\bin\Debug\jim-ostroff-icw-saved-170000-200.txt", 6, 6, _progressData); if (clusterableMatches == null) { return; } var matches = clusterableMatches.Where(match => _toExtend.Contains(match.Match.TestGuid)).ToList(); // Make sure there are no more than 100 concurrent HTTP requests, to avoid overwhelming the Ancestry web site. var throttle = new Throttle(100); // Don't process more than 50 matches at once. This lets the matches finish processing completely // rather than opening requests for all of the matches at onces. var matchThrottle = new Throttle(50); // Now download the shared matches for each match. // This takes much longer than downloading the list of matches themselves.. _progressData.Reset($"Downloading shared matches for {matches.Count} matches...", matches.Count); var matchIndexes = clusterableMatches.ToDictionary(match => match.Match.TestGuid, match => match.Index); var icwTasks = matches.Select(async match => { await matchThrottle.WaitAsync(); var result = await _matchesRetriever.GetMatchesInCommonAsync(guid, match.Match, false, 6, throttle, matchIndexes, _progressData); var coords = new HashSet <int>(result) { match.Index }; return(new { Index = match.Index, Icw = coords, }); }); var icws = await Task.WhenAll(icwTasks); var icwDictionary = icws.ToDictionary(icwTask => icwTask.Index, icwTask => icwTask.Icw); var updatedClusterableMatches = clusterableMatches.Select(match => icwDictionary.ContainsKey(match.Index) ? new ClusterableMatch(match.Index, match.Match, icwDictionary[match.Index]) : match).ToList(); // Save the downloaded data to disk. _progressData.Reset("Saving data..."); var icw = updatedClusterableMatches.ToDictionary( match => match.Match.TestGuid, match => match.Coords.ToList()); var output = new Serialized { TestTakerTestId = guid, Matches = updatedClusterableMatches.Select(match => match.Match).ToList(), MatchIndexes = matchIndexes, Icw = icw }; var fileName = @"C:\Users\JSB\Desktop\Ancestry\bin\Debug\jim-ostroff-icw-saved-extended-170000-200.txt"; FileUtils.WriteAsJson(fileName, output, false); var matchesWithSharedMatches = output.Icw.Where(match => match.Value.Count > 1).ToList(); var averageSharedMatches = matchesWithSharedMatches.Sum(match => match.Value.Count - 1) / (double)matchesWithSharedMatches.Count; _progressData.Reset(DateTime.Now - startTime, $"Done. Downloaded {matches.Count} matches ({matchesWithSharedMatches.Count} with shared matches, averaging {averageSharedMatches:0.#} shared matches"); }