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;
}
}
}
}