LoginSignup
5
3

More than 5 years have passed since last update.

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

Posted at

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

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

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;
            }
        }
    }
}
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3