CoreTweetで再読み込みに対応にする拡張メソッド

[CoreTweet](https://github.com/CoreTweet/CoreTweet)とても便利ですね。
ただ、CoreTweetは、素のTwitterAPIを叩くだけなので、
とりあえず、ある人のツイート全部欲しい、というような要望には、ちょっとコードを書かないといけません。
それもまぁ、テンプレ処理なので、拡張メソッドにしてみました。
また、APIを使い果たしたとしても、スリープし、再取得するというのもできるようにしました。
そのため、放置しておけばなんとかなるというものになります。

こんな感じで、UserTimeLine以外のAPIも拡張メソッドを作るといいと思います。


```csharp:filename
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CoreTweet;
using CoreTweet.Core;

namespace CoreTweet.MyExtend
{
    public class Sample
    {
        /// <summary>
        /// 使い方　
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public IEnumerable<Status> GetUserTweet(string user)
        {
            var token = OAuth2.GetToken("キー", "シークレット");
            //500ツイート取得する。ログはとりあえず、コンソールに書きます。
            foreach (var item in token.GetUserTimeLines(user, 500, new TimeSpan(0, 3, 0), (n) => Console.WriteLine(n)))
            {
                yield return item;
            }
        }
    }

    public static class CoreTweetExtend
    {
        /// <summary>
        /// 指定したscreen_nameのユーザのツイートを指定個数取得する。（Retryなし）
        /// </summary>
        /// <param name="token"></param>
        /// <param name="user_name"></param>
        /// <param name="maxCount"></param>
        /// <returns></returns>
        public static IEnumerable<Status> GetUserTimeLines(this OAuth2Token token, string user_name,int maxCount)
        {
            var list = token.Statuses.UserTimeline(screen_name => user_name, count => 100);
            int c = 0;
            long maxId = long.MaxValue;
            foreach (var item in list)
            {
                maxId = item.Id;
                c++;
                yield return item;
            }
            while(true)
            {
                var list2 = token.Statuses.UserTimeline(screen_name => user_name, count => 100,max_id => (maxId-1).ToString()).ToArray();
                foreach (var item in list2)
                {
                    maxId = item.Id;
                    yield return item;
                    c++;
                    if (maxCount <= c) break;
                }
                if (list2.Length < 20) break;
                if (maxCount <= c) break;
            }
        }

        
        /// <summary>
        /// UserTimelineAPIを使う。もしAPIを使いきっているなら、スリープし、再実行する。
        /// </summary>
        /// <param name="statuses"></param>
        /// <param name="sleepTime"></param>
        /// <param name="report"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static IEnumerable<CoreTweet.Status> UserTimelineRetry(this CoreTweet.Rest.Statuses statuses,TimeSpan sleepTime,Action<string> report, params System.Linq.Expressions.Expression<Func<string, object>>[] parameters)
        {
            CoreTweet.Status[] list2 = new List<CoreTweet.Status>().ToArray();
            bool flag = false;
            try
            {
                list2 = statuses.UserTimeline(parameters).ToArray();
            }
            catch (Exception ex)
            {
                report(ex.Message);
                if (ex.Message == "Rate limit exceeded")
                {
                    flag = true;
                }
                else if (ex.Message == "Over capacity")
                {
                    flag = true;
                }
                else
                {
                    throw ex;
                }
             
            }
            if (flag)
            {
                report("Sleep");
                System.Threading.Thread.Sleep(sleepTime);
                return UserTimelineRetry(statuses,sleepTime,report,parameters);
            }            
            return list2;
        }

        /// <summary>
        /// 指定したscreen_nameのユーザのツイートを指定個数取得する。(Retryあり)
        /// </summary>
        /// <param name="token"></param>
        /// <param name="user_name"></param>
        /// <param name="maxCount"></param>
        /// <param name="sleep"></param>
        /// <param name="report"></param>
        /// <returns></returns>
        public static IEnumerable<Status> GetUserTimeLines(this OAuth2Token token, string user_name, int maxCount,TimeSpan sleep,Action<string> report)
        {
            var list2 = token.Statuses.UserTimelineRetry(sleep,report, screen_name => user_name, count => 100);
            int c = 0;
            long maxId = long.MaxValue;
            foreach (var item in list2)
            {
                maxId = item.Id;
                c++;
                yield return item;
            }
            while (true)
            {
                list2 = token.Statuses.UserTimelineRetry(sleep, report, screen_name => user_name, count => 100, max_id => (maxId - 1).ToString());
                int c1 = 0;
                foreach (var item in list2)
                {
                    maxId = item.Id;
                    yield return item;
                    c++;
                    c1++;
                    if (maxCount <= c) break;
                }
                if (c1 < 20) break;
                if (maxCount <= c) break;
            }
        }
    }
}
```