Example #1
0
        public async void Run(IBackgroundTaskInstance taskInstance)
        {
            AddQuestionsResult result = null;
            BackgroundTaskDeferral deferral = taskInstance.GetDeferral();

            #if DEBUG
            InvokeSimpleToast("Hello from " + taskInstance.Task.Name);
            #endif

            try
            {
                result = await FeedManager.QueryWebsitesAsync();

                #if DEBUG
                InvokeSimpleToast(String.Format(
                    "There are {0} new questions and {1} updated questions.",
                    result.AddedQuestions,
                    result.UpdatedQuestions));
                #endif
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);

                #if DEBUG
                InvokeSimpleToast(ex.Message);
                #endif
            }

            deferral.Complete();
        }
Example #2
0
        // This method can be call simultaneously. Make sure only one thread is touching it.
        public static AddQuestionsResult AddQuestions(string websiteUrl, SyndicationFeed feed, bool skipLatestPubDate)
        {
            AddQuestionsResult globalResult = new AddQuestionsResult();

            DateTimeOffset latestPubDate = SettingsManager.GetLastestPubDate(websiteUrl);
            DateTimeOffset newLatestPubDate = DateTimeOffset.MinValue;
            Debug.WriteLine("{0} Current LastestPubDate is {1}.", websiteUrl, latestPubDate);

            // Wait until the event is set by another thread.
            addEvent.WaitOne();

            try
            {
                CheckSettingsAreLoaded();

                foreach (SyndicationItem item in feed.Items)
                {
                    AddQuestionResult result = AddQuestionResult.None;
                    if (skipLatestPubDate || DateTimeOffset.Compare(item.PublishedDate.DateTime, latestPubDate) > 0)
                    {
                        result = AddQuestion(websiteUrl, item);

                        // Chances are we need to update the LatestPubDate.
                        if (result == AddQuestionResult.Added && item.PublishedDate > newLatestPubDate)
                        {
                            newLatestPubDate = item.PublishedDate;
                            Debug.WriteLine("{0} New LastestPubDate is {1}.", websiteUrl, newLatestPubDate);
                        }
                    }
                    else
                    {
                        result = UpdateQuestion(websiteUrl, item);
                    }

                    switch (result)
                    {
                        case AddQuestionResult.Added:
                            globalResult.AddedQuestions++;
                            break;
                        case AddQuestionResult.Updated:
                            globalResult.UpdatedQuestions++;
                            break;
                    }
                }

                // If the quesiton list did not change, there should not be a new LatestPubDate.
                if (globalResult.AddedQuestions > 0)
                {
                    SettingsManager.SetLastestPubDate(websiteUrl, newLatestPubDate);
                }

                return globalResult;
            }
            finally
            {
                // Set the event, so other threads waiting on it can do their job.
                addEvent.Set();
            }
        }
Example #3
0
        public static IAsyncOperation <AddQuestionsResult> QueryTagAsync(string websiteUrl, string tagEncoded)
        {
            return(AsyncInfo.Run(async(cancellationToken) =>
            {
                // Retrieve questions, skip the LatestPubDate validation and add all questions.
                AddQuestionsResult result = await FeedManager.QuerySingleWebsiteAsync(websiteUrl, tagEncoded, true);

                // Only limit and save questions if list changed.
                if (result.AddedQuestions > 0 || result.UpdatedQuestions > 0)
                {
                    uint removedQuestions = await QuestionsManager.RemoveQuestionsInReadList();
                    await QuestionsManager.LimitTo150AndSaveAsync();
                    FeedManager.UpdateTileAndBadge();
                }

                return result;
            }));
        }
Example #4
0
        // 1. Load settings.
        // 2. query -> Retrieve feeds.
        // 3. skipLatestPubDate -> Add questions.
        // 4. Sort questions (needed to show tile and badge).
        // 5. Update tile.
        // 6. Update badge.
        // TODO: Maybe check for buzz words here.
        public static IAsyncOperation <AddQuestionsResult> QueryWebsitesAsync()
        {
            return(AsyncInfo.Run(async(cancellationToken) =>
            {
                SettingsManager.Load();
                await QuestionsManager.LoadAsync();

                // Query websites in parallel.

                List <Task <AddQuestionsResult> > tasks = new List <Task <AddQuestionsResult> >();
                IEnumerable <string> keys = SettingsManager.GetWebsiteKeys();
                foreach (string website in keys)
                {
                    string query = SettingsManager.ConcatenateAllTags(website);
                    tasks.Add(QuerySingleWebsiteAsync(website, query, false).AsTask());
                }

                if (tasks.Count == 0)
                {
                    // There is nothing to wait.
                    return new AddQuestionsResult();
                }

                await Task.Factory.ContinueWhenAll(tasks.ToArray(), (tasks2) => {});

                // Add up the results.
                AddQuestionsResult result = new AddQuestionsResult();
                foreach (Task <AddQuestionsResult> task in tasks)
                {
                    AddQuestionsResult taskResult = task.Result;
                    result.AddedQuestions += taskResult.AddedQuestions;
                    result.UpdatedQuestions += taskResult.UpdatedQuestions;
                    if (!taskResult.FileFound)
                    {
                        result.FileFound = false;
                    }
                }

                Debug.WriteLine(
                    "{0} questions added, {0} questions modified.",
                    result.AddedQuestions,
                    result.UpdatedQuestions);

                // Only limit and save questions if list changed.
                if (result.AddedQuestions > 0 || result.UpdatedQuestions > 0)
                {
                    uint removedQuestions = await QuestionsManager.RemoveQuestionsInReadList();
                    await QuestionsManager.LimitTo150AndSaveAsync();
                    UpdateTileAndBadge();

                    SettingsManager.SaveLocal(); // Save updated latestPubDate.
                }

                // Update last query date-time, only if all queries were successful.
                if (result.FileFound)
                {
                    SettingsManager.LatestQueryDate = DateTimeOffset.Now;
                }

                return result;
            }));
        }
Example #5
0
        public static IAsyncOperation <AddQuestionsResult> QuerySingleWebsiteAsync(
            string websiteUrl,
            string query,
            bool skipLatestPubDate)
        {
            return(AsyncInfo.Run(async(cancellationToken) =>
            {
                AddQuestionsResult result = new AddQuestionsResult();

                Uri uri;
                if (!SettingsManager.TryCreateUri(websiteUrl, query, out uri))
                {
                    Debugger.Break();
                }

                SyndicationFeed feed = null;
                try
                {
                    client.BypassCacheOnRetrieve = true;
                    feed = await client.RetrieveFeedAsync(uri);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("{0} {1}", websiteUrl, ex.Message);

                    int hr = ex.HResult;
                    int facility = (hr & 0x7FFF0000) / 0xFFFF;
                    int error = hr & 0xFFFF;
                    const int WEB_E_INVALID_XML = unchecked ((int)0x83750002);
                    const int FACILITY_WIN32 = 7;
                    const int FACILITY_HTTP = 25;
                    const int NOT_FOUND = 404;

                    if (hr == WEB_E_INVALID_XML)
                    {
                        // An invalid XML is equivalent to file not found.
                        result.FileFound = false;
                        return result;
                    }
                    else if (facility == FACILITY_HTTP && error == NOT_FOUND)
                    {
                        result.FileFound = false;
                        return result;
                    }
                    else if (facility == FACILITY_HTTP)
                    {
                        // Swallow HTTP errors. Treat them as file not found.
                        result.FileFound = false;
                        return result;
                    }
                    else if (facility == FACILITY_WIN32 && error > 12001 && error < 12156)
                    {
                        // Swallow WININET errors. Treat as file not found.
                        result.FileFound = false;
                        return result;
                    }
                    else
                    {
                        throw;
                    }
                }

                result = QuestionsManager.AddQuestions(websiteUrl, feed, skipLatestPubDate);
                result.FileFound = true;
                return result;
            }));
        }
Example #6
0
        // This method can be call simultaneously. Make sure only one thread is touching it.
        public static AddQuestionsResult AddQuestions(string websiteUrl, SyndicationFeed feed, bool skipLatestPubDate)
        {
            AddQuestionsResult globalResult = new AddQuestionsResult();

            DateTimeOffset latestPubDate    = SettingsManager.GetLastestPubDate(websiteUrl);
            DateTimeOffset newLatestPubDate = DateTimeOffset.MinValue;

            Debug.WriteLine("{0} Current LastestPubDate is {1}.", websiteUrl, latestPubDate);

            // Wait until the event is set by another thread.
            addEvent.WaitOne();

            try
            {
                CheckSettingsAreLoaded();

                foreach (SyndicationItem item in feed.Items)
                {
                    AddQuestionResult result = AddQuestionResult.None;
                    if (skipLatestPubDate || DateTimeOffset.Compare(item.PublishedDate.DateTime, latestPubDate) > 0)
                    {
                        result = AddQuestion(websiteUrl, item);

                        // Chances are we need to update the LatestPubDate.
                        if (result == AddQuestionResult.Added && item.PublishedDate > newLatestPubDate)
                        {
                            newLatestPubDate = item.PublishedDate;
                            Debug.WriteLine("{0} New LastestPubDate is {1}.", websiteUrl, newLatestPubDate);
                        }
                    }
                    else
                    {
                        result = UpdateQuestion(websiteUrl, item);
                    }

                    switch (result)
                    {
                    case AddQuestionResult.Added:
                        globalResult.AddedQuestions++;
                        break;

                    case AddQuestionResult.Updated:
                        globalResult.UpdatedQuestions++;
                        break;
                    }
                }

                // If the quesiton list did not change, there should not be a new LatestPubDate.
                if (globalResult.AddedQuestions > 0)
                {
                    SettingsManager.SetLastestPubDate(websiteUrl, newLatestPubDate);
                }

                return(globalResult);
            }
            finally
            {
                // Set the event, so other threads waiting on it can do their job.
                addEvent.Set();
            }
        }
Example #7
0
        public static IAsyncOperation<AddQuestionsResult> QuerySingleWebsiteAsync(
            string websiteUrl,
            string query,
            bool skipLatestPubDate)
        {
            return AsyncInfo.Run(async (cancellationToken) =>
            {
                AddQuestionsResult result = new AddQuestionsResult();

                Uri uri;
                if (!SettingsManager.TryCreateUri(websiteUrl, query, out uri))
                {
                    Debugger.Break();
                }

                SyndicationFeed feed = null;
                try
                {
                    client.BypassCacheOnRetrieve = true;
                    feed = await client.RetrieveFeedAsync(uri);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("{0} {1}", websiteUrl, ex.Message);

                    int hr = ex.HResult;
                    int facility = (hr & 0x7FFF0000) / 0xFFFF;
                    int error = hr & 0xFFFF;
                    const int WEB_E_INVALID_XML = unchecked((int)0x83750002);
                    const int FACILITY_WIN32 = 7;
                    const int FACILITY_HTTP = 25;
                    const int NOT_FOUND = 404;

                    if (hr == WEB_E_INVALID_XML)
                    {
                        // An invalid XML is equivalent to file not found.
                        result.FileFound = false;
                        return result;
                    }
                    else if (facility == FACILITY_HTTP && error == NOT_FOUND)
                    {
                        result.FileFound = false;
                        return result;
                    }
                    else if (facility == FACILITY_HTTP)
                    {
                        // Swallow HTTP errors. Treat them as file not found.
                        result.FileFound = false;
                        return result;
                    }
                    else if (facility == FACILITY_WIN32 && error > 12001 && error < 12156)
                    {
                        // Swallow WININET errors. Treat as file not found.
                        result.FileFound = false;
                        return result;
                    }
                    else
                    {
                        throw;
                    }
                }

                result = QuestionsManager.AddQuestions(websiteUrl, feed, skipLatestPubDate);
                result.FileFound = true;
                return result;
            });
        }
Example #8
0
        // 1. Load settings.
        // 2. query -> Retrieve feeds.
        // 3. skipLatestPubDate -> Add questions.
        // 4. Sort questions (needed to show tile and badge).
        // 5. Update tile.
        // 6. Update badge.
        // TODO: Maybe check for buzz words here.
        public static IAsyncOperation<AddQuestionsResult> QueryWebsitesAsync()
        {
            return AsyncInfo.Run(async (cancellationToken) =>
            {
                SettingsManager.Load();
                await QuestionsManager.LoadAsync();

                // Query websites in parallel.

                List<Task<AddQuestionsResult>> tasks = new List<Task<AddQuestionsResult>>();
                IEnumerable<string> keys = SettingsManager.GetWebsiteKeys();
                foreach (string website in keys)
                {
                    string query = SettingsManager.ConcatenateAllTags(website);
                    tasks.Add(QuerySingleWebsiteAsync(website, query, false).AsTask());
                }

                if (tasks.Count == 0)
                {
                    // There is nothing to wait.
                    return new AddQuestionsResult();
                }

                await Task.Factory.ContinueWhenAll(tasks.ToArray(), (tasks2) => {});

                // Add up the results.
                AddQuestionsResult result = new AddQuestionsResult();
                foreach (Task<AddQuestionsResult> task in tasks)
                {
                    AddQuestionsResult taskResult = task.Result;
                    result.AddedQuestions += taskResult.AddedQuestions;
                    result.UpdatedQuestions += taskResult.UpdatedQuestions;
                    if (!taskResult.FileFound)
                    {
                        result.FileFound = false;
                    }
                }

                Debug.WriteLine(
                    "{0} questions added, {0} questions modified.",
                    result.AddedQuestions,
                    result.UpdatedQuestions);

                // Only limit and save questions if list changed.
                if (result.AddedQuestions > 0 || result.UpdatedQuestions > 0)
                {
                    uint removedQuestions = await QuestionsManager.RemoveQuestionsInReadList();
                    await QuestionsManager.LimitTo150AndSaveAsync();
                    UpdateTileAndBadge();

                    SettingsManager.SaveLocal(); // Save updated latestPubDate.
                }

                // Update last query date-time, only if all queries were successful.
                if (result.FileFound)
                {
                    SettingsManager.LatestQueryDate = DateTimeOffset.Now;
                }

                return result;
            });
        }