Created
April 26, 2010 13:32
-
-
Save karno/379328 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using Std.Tweak; | |
namespace Mintw | |
{ | |
/// <summary> | |
/// Twitterへのアクセサ | |
/// </summary> | |
public class Access | |
{ | |
//OAuth APIアクセスクラス | |
public MintwOAuth api = new MintwOAuth(); | |
//Mentionの受信カウンタ | |
public int MentionCnt = 0; | |
//DMの受信カウンタ | |
public int DmCnt = 0; | |
/// <summary> | |
/// アクセサの初期化 | |
/// </summary> | |
public void Init() | |
{ | |
Kernel.MinitTimer = new System.Threading.Timer(TimerCallback, null, 0, 1000 * 60); | |
} | |
/// <summary> | |
/// 一分ごとに呼ばれるタイマーのコールバック | |
/// </summary> | |
public void TimerCallback(object o) | |
{ | |
AccessMain(false); | |
} | |
/// <summary> | |
/// Twitterへアクセス | |
/// </summary> | |
/// <remarks> | |
/// 1分ごとに呼ばれることを想定。 | |
/// </remarks> | |
/// <param name="enforced">必ずチェックをするか(falseならカウンタ回数が規定値以上の場合にチェック)</param> | |
public void AccessMain(bool enforced) | |
{ | |
//カウンタ更新 | |
MentionCnt++; | |
DmCnt++; | |
//新着ステータスのリスト | |
List<TwitterStatusBase> received = new List<TwitterStatusBase>(); | |
//DMが来たかのフラグ | |
bool DMreceived = false; | |
if (enforced || MentionCnt >= Kernel.Config.MentionInverval) | |
{ | |
//カウンタ初期化 | |
MentionCnt = 0; | |
//Mentionsのチェック | |
var nr = CheckMentions(); | |
if (nr != null) | |
received.AddRange(nr); | |
} | |
if (enforced || DmCnt >= Kernel.Config.DMInterval) | |
{ | |
//カウンタ初期化 | |
DmCnt = 0; | |
//DMのチェック | |
var nr = CheckDms(); | |
if (nr != null) | |
{ | |
received.AddRange(nr); | |
DMreceived = true; | |
} | |
} | |
if (received.Count > 0 && OnReceivedNew != null) | |
{ | |
//戻り値生成 with LINQ | |
OnReceivedNew.Invoke( | |
from s in received | |
orderby s.CreatedAt | |
select s, | |
DMreceived); | |
} | |
} | |
/// <summary> | |
/// 受信時にExceptionが投げられました | |
/// </summary> | |
public event Action<Exception> OnThrownException; | |
/// <summary> | |
/// 新着ステータスがあります(boolがtrueならDMを含んでいます) | |
/// </summary> | |
public event Action<IEnumerable<TwitterStatusBase>, bool> OnReceivedNew; | |
/// <summary> | |
/// 新着Mentionsを列挙 | |
/// </summary> | |
/// <returns>ステータスの列挙 もしくは NULL</returns> | |
private IEnumerable<TwitterStatusBase> CheckMentions() | |
{ | |
//アクセス情報更新 | |
UpdateAccessInformations(); | |
try | |
{ | |
//受信とソート | |
var mentions = from s in api.GetMentions() | |
orderby s.CreatedAt descending | |
select (TwitterStatusBase)s; | |
if (mentions != null) | |
//フィルタして返す | |
return FilterReceivedStatuses(mentions, ref Kernel.prevRecvMentionId); | |
} | |
catch (Exception e) | |
{ | |
//エラーの通知とNULL返し | |
if (OnThrownException != null) | |
OnThrownException.Invoke(e); | |
} | |
//受信がNULLか、エラーが発生している | |
return null; | |
} | |
/// <summary> | |
/// 新着DMを列挙 | |
/// </summary> | |
/// <returns>ステータスの列挙 もしくは NULL</returns> | |
private IEnumerable<TwitterStatusBase> CheckDms() | |
{ | |
//アクセス情報更新 | |
UpdateAccessInformations(); | |
try | |
{ | |
//受信とソート | |
var dms = from s in api.GetDirectMessages() | |
orderby s.CreatedAt descending | |
select (TwitterStatusBase)s; | |
if (dms != null) | |
//フィルタして返す | |
return FilterReceivedStatuses(dms, ref Kernel.prevRecvDmId); | |
} | |
catch (Exception e) | |
{ | |
//エラー通知 | |
if (OnThrownException != null) | |
OnThrownException.Invoke(e); | |
} | |
//受信がNULLか、エラーが発生している | |
return null; | |
} | |
/// <summary> | |
/// ステータスをフィルタ | |
/// </summary> | |
/// <param name="received">受信したステータスの列挙</param> | |
/// <param name="prevReceivedId">IDの列挙</param> | |
/// <returns>新着ステータスの列挙 もしくは NULL</returns> | |
private IEnumerable<TwitterStatusBase> FilterReceivedStatuses(IEnumerable<TwitterStatusBase> received, ref long prevReceivedId) | |
{ | |
if (prevReceivedId == 0) | |
{ | |
//旧IDが無い→新着? | |
foreach (var recv in received) | |
{ | |
prevReceivedId = recv.Id; | |
break; | |
} | |
} | |
else | |
{ | |
//前回の最新IDを代入 | |
long firstId = prevReceivedId; | |
foreach (var recv in received) | |
{ | |
//最新IDを反映 | |
prevReceivedId = recv.Id; | |
//そしてすぐ抜ける | |
break; | |
} | |
//旧最新IDよりもIDが大きいステータスのみを抽出して列挙 | |
return from s in received | |
where s.Id > firstId | |
select s; | |
} | |
//列挙されるべきステータスは無い | |
return null; | |
} | |
/// <summary> | |
/// アクセス情報の更新 | |
/// </summary> | |
private void UpdateAccessInformations() | |
{ | |
api.Secret = Kernel.Config.UserSecret; | |
api.Token = Kernel.Config.UserToken; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment