svnno****@sourc*****
svnno****@sourc*****
2010年 11月 22日 (月) 14:06:13 JST
Revision: 1091 http://sourceforge.jp/projects/tween/svn/view?view=rev&revision=1091 Author: syo68k Date: 2010-11-22 14:06:13 +0900 (Mon, 22 Nov 2010) Log Message: ----------- home_timelineとmentionsをjsonでの取得に Modified Paths: -------------- branches/UserStream/Tween/Connection/HttpTwitter.vb branches/UserStream/Tween/Tween.vbproj branches/UserStream/Tween/Twitter.vb Added Paths: ----------- branches/UserStream/Tween/DataModel.vb -------------- next part -------------- Modified: branches/UserStream/Tween/Connection/HttpTwitter.vb =================================================================== --- branches/UserStream/Tween/Connection/HttpTwitter.vb 2010-11-22 04:49:19 UTC (rev 1090) +++ branches/UserStream/Tween/Connection/HttpTwitter.vb 2010-11-22 05:06:13 UTC (rev 1091) @@ -322,7 +322,7 @@ End If Return httpCon.GetContent(GetMethod, _ - CreateTwitterUri("/1/statuses/home_timeline.xml"), _ + CreateTwitterUri("/1/statuses/home_timeline.json"), _ param, _ content, _ TwitterApiInfo.HttpHeaders, _ @@ -342,7 +342,7 @@ End If Return httpCon.GetContent(GetMethod, _ - CreateTwitterUri("/1/statuses/mentions.xml"), _ + CreateTwitterUri("/1/statuses/mentions.json"), _ param, _ content, _ TwitterApiInfo.HttpHeaders, _ Added: branches/UserStream/Tween/DataModel.vb =================================================================== --- branches/UserStream/Tween/DataModel.vb (rev 0) +++ branches/UserStream/Tween/DataModel.vb 2010-11-22 05:06:13 UTC (rev 1091) @@ -0,0 +1,146 @@ +Imports System.Runtime.InteropServices +Imports System.Runtime.Serialization + +Public Class DataModel + + <DataContract()> _ + Public Class urls + <DataMember(Name:="urls")> Public urls As String + <DataMember(Name:="indices")> Public indices(2) As Integer + End Class + + <DataContract()> _ + Public Class hashtags + <DataMember(Name:="indices")> Public indices(2) As Integer + <DataMember(Name:="text")> Public text As String + End Class + + <DataContract()> _ + Public Class user_mentions + <DataMember(Name:="indices")> Public indices(2) As Integer + <DataMember(Name:="screen_name")> Public screen_name As String + <DataMember(Name:="name")> Public _name As String + <DataMember(Name:="id")> Public id As Int64 + End Class + + <DataContract()> _ + Public Class entities + <DataMember(Name:="urls")> Public urls() As urls + <DataMember(Name:="hashtags")> Public hashtags() As hashtags + <DataMember(Name:="user_mentions")> Public user_mentions() As user_mentions + End Class + + <DataContract()> _ + Public Class user + <DataMember(Name:="statuses_count")> Public statuses_count As Int64 + <DataMember(Name:="profile_sidebar_fill_color")> Public profile_sidebar_fill_color As String + <DataMember(Name:="show_all_inline_media")> Public show_all_inline_media As Boolean + <DataMember(Name:="profile_use_background_image")> Public profile_use_background_image As Boolean + <DataMember(Name:="contributors_enabled")> Public contributors_enabled As Boolean + <DataMember(Name:="profile_sidebar_border_color")> Public profile_sidebar_border_color As String + <DataMember(Name:="location")> Public location As String + <DataMember(Name:="geo_enabled")> Public geo_enabled As Boolean + <DataMember(Name:="description")> Public description As String + <DataMember(Name:="friends_count")> Public friends_count As Integer + <DataMember(Name:="verified")> Public verified As Boolean + <DataMember(Name:="favourites_count")> Public favourites_count As Integer + <DataMember(Name:="created_at")> Public created_at As String + <DataMember(Name:="profile_background_color")> Public profile_background_color As String + <DataMember(Name:="follow_request_sent")> Public follow_request_sent As String + <DataMember(Name:="time_zone")> Public time_zone As String + <DataMember(Name:="followers_count")> Public followers_count As Integer + <DataMember(Name:="url")> Public url As String + <DataMember(Name:="profile_image_url")> Public profile_image_url As String + <DataMember(Name:="notifications")> Public notifications As String + <DataMember(Name:="profile_text_color")> Public profile_text_color As String + <DataMember(Name:="protected")> Public [protected] As Boolean + <DataMember(Name:="id_str")> Public id_str As String + <DataMember(Name:="lang")> Public lang As String + <DataMember(Name:="profile_background_image_url")> Public profile_background_image_url As String + <DataMember(Name:="screen_name")> Public screen_name As String + <DataMember(Name:="name")> Public _name As String + <DataMember(Name:="following")> Public following As String + <DataMember(Name:="profile_link_color")> Public profile_link_color As String + <DataMember(Name:="id")> Public id As Int64 + <DataMember(Name:="listed_count")> Public listed_count As Integer + <DataMember(Name:="profile_background_tile")> Public profile_background_tile As Boolean + <DataMember(Name:="utc_offset")> Public utc_offset As String + <DataMember(Name:="place")> Public place As place + End Class + + <DataContract()> _ + Public Class coordinates + <DataMember(Name:="type")> Public type As String + <DataMember(Name:="coordinates")> Public _coordinates(2) As String + End Class + + <DataContract()> _ + Public Class geo + <DataMember(Name:="type", IsRequired:=False)> Public type As String + <DataMember(Name:="coordinates")> Public _coordinates(2) As String + End Class + + <DataContract()> _ + Public Class bounding_box + <DataMember(Name:="type")> Public type As String + <DataMember(Name:="coordinates")> Public _coordinates(2) As String + End Class + + <DataContract()> _ + Public Class place + <DataMember(Name:="url")> Public url As String + <DataMember(Name:="bounding_box")> Public bounding_box As bounding_box + <DataMember(Name:="street_address")> Public street_address As String + <DataMember(Name:="full_name")> Public full_name As String + <DataMember(Name:="name")> Public _name As String + <DataMember(Name:="country_code")> Public country_code As String + <DataMember(Name:="id")> Public id As String + <DataMember(Name:="country")> Public country As String + <DataMember(Name:="place_type")> Public place_type As String + End Class + + <DataContract()> _ + Public Class retweeted_status + <DataMember(Name:="coordinates")> Public coordinates As coordinates + <DataMember(Name:="geo")> Public geo As geo + <DataMember(Name:="in_reply_to_user_id")> Public in_reply_to_user_id As String + <DataMember(Name:="source")> Public source As String + <DataMember(Name:="user")> Public user As user + <DataMember(Name:="in_reply_to_screen_name")> Public in_reply_to_screen_name As String + <DataMember(Name:="created_at")> Public created_at As String + <DataMember(Name:="contributors")> Public contributors As String + <DataMember(Name:="favorited")> Public favorited As Boolean + <DataMember(Name:="truncated")> Public truncated As Boolean + <DataMember(Name:="id")> Public id As Int64 + <DataMember(Name:="annotations")> Public annotations As String + <DataMember(Name:="place")> Public place As place + <DataMember(Name:="in_reply_to_status_id")> Public in_reply_to_status_id As String + <DataMember(Name:="text")> Public text As String + End Class + + <DataContract()> _ + Public Class status + <DataMember(Name:="in_reply_to_status_id_str")> Public in_reply_to_status_id_str As String + <DataMember(Name:="contributors")> Public contributors As String + <DataMember(Name:="in_reply_to_screen_name")> Public in_reply_to_screen_name As String + <DataMember(Name:="in_reply_to_status_id")> Public in_reply_to_status_id As String + <DataMember(Name:="in_reply_to_user_id_str")> Public in_reply_to_user_id_str As String + <DataMember(Name:="retweet_count")> Public retweet_count As String + <DataMember(Name:="created_at")> Public created_at As String + <DataMember(Name:="geo")> Public geo As geo + <DataMember(Name:="retweeted")> Public retweeted As Boolean + <DataMember(Name:="in_reply_to_user_id")> Public in_reply_to_user_id As String + <DataMember(Name:="source")> Public source As String + <DataMember(Name:="id_str")> Public id_str As String + <DataMember(Name:="coordinates", IsRequired:=False)> Public coordinates As coordinates + <DataMember(Name:="truncated")> Public truncated As Boolean + <DataMember(Name:="place")> Public place As String + <DataMember(Name:="user")> Public user As user + <DataMember(Name:="retweeted_status", IsRequired:=False)> Public retweeted_status As retweeted_status + <DataMember(Name:="id")> Public id As Int64 + <DataMember(Name:="favorited")> Public favorited As Boolean + <DataMember(Name:="text")> Public text As String + End Class + + +End Class Modified: branches/UserStream/Tween/Tween.vbproj =================================================================== --- branches/UserStream/Tween/Tween.vbproj 2010-11-22 04:49:19 UTC (rev 1090) +++ branches/UserStream/Tween/Tween.vbproj 2010-11-22 05:06:13 UTC (rev 1091) @@ -89,10 +89,14 @@ <PlatformTarget>x86</PlatformTarget> <WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors> </PropertyGroup> + <PropertyGroup> + <OptionInfer>On</OptionInfer> + </PropertyGroup> <ItemGroup> <Reference Include="System" /> <Reference Include="System.DirectoryServices" /> <Reference Include="System.Drawing" /> + <Reference Include="System.Runtime.Serialization" /> <Reference Include="System.Web" /> <Reference Include="System.Windows.Forms" /> <Reference Include="System.XML" /> @@ -126,6 +130,7 @@ <Compile Include="Connection\TwitVideo.vb" /> <Compile Include="Connection\imgly.vb" /> <Compile Include="Connection\yfrog.vb" /> + <Compile Include="DataModel.vb" /> <Compile Include="DetailsListView.vb"> <SubType>Component</SubType> </Compile> Modified: branches/UserStream/Tween/Twitter.vb =================================================================== --- branches/UserStream/Tween/Twitter.vb 2010-11-22 04:49:19 UTC (rev 1090) +++ branches/UserStream/Tween/Twitter.vb 2010-11-22 05:06:13 UTC (rev 1091) @@ -32,6 +32,7 @@ Imports System.Net Imports System.Reflection Imports System.Reflection.MethodBase +Imports System.Runtime.Serialization.Json Public Class Twitter @@ -454,7 +455,7 @@ xNode = xd.SelectSingleNode("/status/user/description/text()") If xNode IsNot Nothing Then _bio = xNode.Value xNode = xd.SelectSingleNode("/status/user/id/text()") - If xNode IsNot Nothing Then _userIdNo = xNode.Value + If xNode IsNot Nothing Then _UserIdNo = xNode.Value Catch ex As Exception Return "" End Try @@ -1388,12 +1389,148 @@ End Select If gType = WORKERTYPE.Timeline Then - Return CreatePostsFromXml(content, gType, Nothing, read, count, Me.minHomeTimeline) + + Return CreatePostsFromJson(content, gType, Nothing, read, count, Me.minHomeTimeline) + 'Return CreatePostsFromXml(content, gType, Nothing, read, count, Me.minHomeTimeline) Else - Return CreatePostsFromXml(content, gType, Nothing, read, count, Me.minMentions) + 'Return CreatePostsFromXml(content, gType, Nothing, read, count, Me.minMentions) + Return CreatePostsFromJson(content, gType, Nothing, read, count, Me.minMentions) End If End Function + Private Function CreatePostsFromJson(ByVal content As String, ByVal gType As WORKERTYPE, ByVal tab As TabClass, ByVal read As Boolean, ByVal count As Integer, ByRef minimumId As Long) As String + Dim stream As New MemoryStream(Encoding.Unicode.GetBytes(content)) + Dim serializer As New DataContractJsonSerializer(GetType(List(Of DataModel.status))) + Dim item As List(Of DataModel.status) + + Dim arIdx As Integer = -1 + Dim dlgt(300) As GetIconImageDelegate 'countQueryに合わせる + Dim ar(300) As IAsyncResult 'countQueryに合わせる +#If 0 Then + item = DirectCast(serializer.ReadObject(stream), List(Of DataModel.status)) +#Else + ' エラーチェックはまだ行わない + Try + item = DirectCast(serializer.ReadObject(stream), List(Of DataModel.status)) + Catch ex As Exception + TraceOut(content) + Return "Invalid Json!" + End Try +#End If + + For Each status As DataModel.status In item + Dim post As New PostClass + Try + post.Id = status.id + If minimumId > post.Id Then minimumId = post.Id + '二重取得回避 + SyncLock LockObj + If tab Is Nothing Then + If TabInformations.GetInstance.ContainsKey(post.Id) Then Continue For + Else + If TabInformations.GetInstance.ContainsKey(post.Id, tab.TabName) Then Continue For + End If + End SyncLock + If status.retweeted_status IsNot Nothing Then + Dim retweeted As DataModel.retweeted_status = status.retweeted_status + post.PDate = DateTime.ParseExact(retweeted.created_at, "ddd MMM dd HH:mm:ss zzzz yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None) + 'Id + post.RetweetedId = retweeted.id + '本文 + post.Data = retweeted.text + 'Source取得(htmlの場合は、中身を取り出し) + post.Source = retweeted.source + 'Reply先 + Long.TryParse(retweeted.in_reply_to_status_id, post.InReplyToId) + post.InReplyToUser = retweeted.in_reply_to_screen_name + post.IsFav = TabInformations.GetInstance.GetTabByType(TabUsageType.Favorites).Contains(post.RetweetedId) + + '以下、ユーザー情報 + Dim user As DataModel.user = retweeted.user + post.Uid = user.id + post.Name = user.screen_name + post.Nickname = user._name + post.ImageUrl = user.profile_image_url + post.IsProtect = user.protected + If post.IsMe Then _UserIdNo = post.Uid.ToString() + + 'Retweetした人 + post.RetweetedBy = status.user.screen_name + Else + post.PDate = DateTime.ParseExact(status.created_at, "ddd MMM dd HH:mm:ss zzzz yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None) + '本文 + post.Data = status.text + 'Source取得(htmlの場合は、中身を取り出し) + post.Source = status.source + Long.TryParse(status.in_reply_to_status_id, post.InReplyToId) + post.InReplyToUser = status.in_reply_to_screen_name + + post.IsFav = status.favorited + + '以下、ユーザー情報 + Dim user As DataModel.user = status.user + post.Uid = user.id + post.Name = user.screen_name + post.Nickname = user._name + post.ImageUrl = user.profile_image_url + post.IsProtect = user.protected + post.IsMe = post.Name.ToLower.Equals(_uid) + If post.IsMe Then _UserIdNo = post.Uid.ToString + End If + 'HTMLに整形 + post.OriginalData = CreateHtmlAnchor(post.Data, post.ReplyToList) + post.Data = HttpUtility.HtmlDecode(post.Data) + post.Data = post.Data.Replace("<3", "♡") + 'Source整形 + CreateSource(post) + + post.IsRead = read + If gType = WORKERTYPE.Timeline OrElse tab IsNot Nothing Then + post.IsReply = post.ReplyToList.Contains(_uid) + Else + post.IsReply = True + End If + post.IsExcludeReply = False + + If post.IsMe Then + post.IsOwl = False + Else + If followerId.Count > 0 Then post.IsOwl = Not followerId.Contains(post.Uid) + End If + If post.IsMe AndAlso Not read AndAlso _readOwnPost Then post.IsRead = True + + post.IsDm = False + If tab IsNot Nothing Then post.RelTabName = tab.TabName + Catch ex As Exception + TraceOut(content) + MessageBox.Show("Parse Error(CreatePostsFromJson)") + Continue For + End Try + '非同期アイコン取得&StatusDictionaryに追加 + arIdx += 1 + If arIdx > dlgt.Length - 1 Then + arIdx -= 1 + Exit For + End If + dlgt(arIdx) = New GetIconImageDelegate(AddressOf GetIconImage) + ar(arIdx) = dlgt(arIdx).BeginInvoke(post, Nothing, Nothing) + Next + 'アイコン取得完了待ち + For i As Integer = 0 To arIdx + Try + dlgt(i).EndInvoke(ar(i)) + Catch ex As IndexOutOfRangeException + Throw New IndexOutOfRangeException(String.Format("i={0},dlgt.Length={1},ar.Length={2},arIdx={3}", i, dlgt.Length, ar.Length, arIdx)) + Catch ex As Exception + '最後までendinvoke回す(ゾンビ化回避) + ex.Data("IsTerminatePermission") = False + Throw + End Try + Next + + Return "" + End Function + 'Public Overloads Function GetListStatus(ByVal read As Boolean, _ ' ByVal tab As TabClass, _ ' ByVal more As Boolean) As String