示例#1
0
        /// <summary>
        ///		WebからRSSフィードを取得します。
        /// </summary>
        /// <returns>すぱこーRSSフィードのコンテンツを格納したリスト</returns>
        private async Task <IEnumerable <SpacomicRSSItem> > GetRSSCore()
        {
            List <SpacomicRSSItem> list = new List <SpacomicRSSItem>();

            foreach (var sause in spacoSause)
            {
                // オフセット位置
                int offset = 0;
                // 続けて取得する必要があるかを表すフラグ
                bool isContinue = true;

                do
                {
                    string url = $"{sause.RSSFeedURL}?offset={offset}";
                    using (XmlReader reader = await Task.Run(() => SpacoRSSClient.GetXmlReaderAsync(url, cancellationTokenSource.Token))) {
                        SpacoRSSReader srr = await Task.Run(() => SpacoRSSReader.LoadAsync(reader, cancellationTokenSource.Token));

                        // すぱこーRSSフィードのチャネル情報を設定します。
                        if (!SauseItems.ContainsKey(sause.Type))
                        {
                            SauseItems[sause.Type] = new SpacoRSSSause {
                                Title       = srr.Title,
                                Description = srr.Description,
                                Author      = srr.Author,
                                Link        = srr.Link,
                                PubDate     = srr.PubDate,
                                BannerURL   = srr.BannerURL
                            };
                        }

                        // 取得したコンテンツの数を取得します。
                        int count = srr.Items.Count();
                        if (count > 0)
                        {
                            offset += count;
                        }
                        // なければ、現在ソースからののRSSフィードの取得を終了します。
                        else
                        {
                            isContinue = false;
                        }

                        // 利用可能なコンテンツを抽出します。
                        list.AddRange(
                            srr.Items.Where(_ => _.IsAvailable)
                            .Select(_ => new SpacomicRSSItem(sause.Type, _))
                            .ToList()
                            );
                    }
                } while(isContinue);
            }
            return(list);
        }
示例#2
0
        /// <summary>
        ///		RSSフィードを取得(保存済みのローカルファイルから読み込み or Webから取得)します。
        /// </summary>
        /// <param name="forceReload">強制的にWebから取得するフラグ</param>
        public async Task GetRSS(bool forceReload = false)
        {
            // 初期化
            GetRSSResult result = GetRSSResult.Succeeded;

            SauseItems.Clear();
            Items.Clear();
            cancellationTokenSource = new CancellationTokenSource();
            GetRSSStarted(this, null);

            try {
                // Webからの再取得をリクエストされた時
                if (forceReload)
                {
                    try {
                        Items.AddRange((await GetRSSCore()).OrderByDescending(_ => _.PubDate));
                        // 取得したすぱこーRSSフィードのデータをローカルファイルに保存します。
                        await SpacomicLocalIO.SaveSpacoRSSSauseFile(SauseItems);

                        await SpacomicLocalIO.SaveRSSCollectionFile(Items);
                    }
                    // Webからの再取得に失敗した場合、ローカルファイルからリストアします。
                    // Itemsが空であれば、保存済みのローカルファイルは、再取得する前のすぱこーRSSフィードのデータが残っています。
                    catch (Exception) when(!Items.Any())
                    {
                        // 保存済みのローカルファイルからリストア
                        var spacoRSSauseFromLocal = await SpacomicLocalIO.LoadSpacoRSSSauseFile();

                        var spacoRSSListFromLocal = await SpacomicLocalIO.LoadRSSCollectionFile();

                        // 保存済みのローカルファイルからのリストアが成功した時
                        if (spacoRSSauseFromLocal.ResultCode == GetRSSResult.Succeeded && spacoRSSListFromLocal.ResultCode == GetRSSResult.Succeeded)
                        {
                            foreach (var item in spacoRSSauseFromLocal.Items)
                            {
                                SauseItems[item.Key] = item.Value;
                            }
                            Items.AddRange(spacoRSSListFromLocal.Items);
                            result = GetRSSResult.LocalDataRestored;
                        }
                        // リストアに失敗した場合、例外をリスローします。
                        else
                        {
                            throw;
                        }
                    }
                }
                else
                {
                    // 保存済みのローカルファイルから読み込み
                    var spacoRSSauseFromLocal = await SpacomicLocalIO.LoadSpacoRSSSauseFile();

                    var spacoRSSListFromLocal = await SpacomicLocalIO.LoadRSSCollectionFile();

                    // 保存済みのローカルファイルからの読み込みが成功した時
                    if (spacoRSSauseFromLocal.ResultCode == GetRSSResult.Succeeded && spacoRSSListFromLocal.ResultCode == GetRSSResult.Succeeded)
                    {
                        foreach (var item in spacoRSSauseFromLocal.Items)
                        {
                            SauseItems[item.Key] = item.Value;
                        }
                        Items.AddRange(spacoRSSListFromLocal.Items);

                        // Web上に最新話があるかどうかチェックします。
                        CheckNewContents();
                    }
                    // ローカルファイルからの読み込みに失敗した場合、Webから取得します
                    else
                    {
                        Items.AddRange((await GetRSSCore()).OrderByDescending(_ => _.PubDate));
                        await SpacomicLocalIO.SaveSpacoRSSSauseFile(SauseItems);

                        await SpacomicLocalIO.SaveRSSCollectionFile(Items);
                    }
                }
            }
            catch (OperationCanceledException) {
                SauseItems.Clear();
                Items.Clear();
                result = GetRSSResult.Canceled;
            }
            catch (Exception) {
                SauseItems.Clear();
                Items.Clear();
                result = GetRSSResult.Failed;
            }
            finally {
                cancellationTokenSource.Dispose();
            }
            // すぱこーRSSフィードの取得が完了したことをViewModel側に通知します。
            GetRSSCompleted?.Invoke(this, result);
        }