修訂 | b0f5451e866e1294f5917bfe6417f45b4c8aeef6 (tree) |
---|---|
時間 | 2023-07-05 08:44:19 |
作者 | Kimura Youichi <kim.upsilon@bucy...> |
Commiter | Kimura Youichi |
Merge branch 'develop' into release
@@ -110,5 +110,18 @@ namespace OpenTween.Api.GraphQL | ||
110 | 110 | Assert.Equal("1617126084138659840", post.RetweetedId!.Id); |
111 | 111 | Assert.Equal(514241801L, post.UserId); |
112 | 112 | } |
113 | + | |
114 | + [Fact] | |
115 | + public void ToStatus_WithTwitterPostFactory_TweetWithVisibility_Test() | |
116 | + { | |
117 | + var rootElm = this.LoadResponseDocument("TimelineTweet_TweetWithVisibility.json"); | |
118 | + var timelineTweet = new TimelineTweet(rootElm); | |
119 | + var status = timelineTweet.ToTwitterStatus(); | |
120 | + var postFactory = new TwitterPostFactory(this.CreateTabInfo()); | |
121 | + var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet<long>()); | |
122 | + | |
123 | + Assert.Equal("1602775353088524288", post.StatusId.Id); | |
124 | + Assert.Equal(357750891L, post.UserId); | |
125 | + } | |
113 | 126 | } |
114 | 127 | } |
@@ -19,6 +19,11 @@ | ||
19 | 19 | // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, |
20 | 20 | // Boston, MA 02110-1301, USA. |
21 | 21 | |
22 | +using System.IO; | |
23 | +using System.Runtime.Serialization.Json; | |
24 | +using System.Text; | |
25 | +using System.Xml; | |
26 | +using System.Xml.Linq; | |
22 | 27 | using Xunit; |
23 | 28 | |
24 | 29 | namespace OpenTween.Api |
@@ -34,5 +39,38 @@ namespace OpenTween.Api | ||
34 | 39 | [InlineData("\U0001D11E", @"\uD834\uDD1E")] |
35 | 40 | public void EscapeJsonString_Test(string targetText, string expectedText) |
36 | 41 | => Assert.Equal(expectedText, JsonUtils.EscapeJsonString(targetText)); |
42 | + | |
43 | + [Fact] | |
44 | + public void JsonXmlToString_WholeTest() | |
45 | + { | |
46 | + var json = """{"hoge":{"aaa":12345}}"""; | |
47 | + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); | |
48 | + using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max); | |
49 | + var rootElement = XElement.Load(jsonReader); | |
50 | + | |
51 | + Assert.Equal("""{"hoge":{"aaa":12345}}""", JsonUtils.JsonXmlToString(rootElement)); | |
52 | + } | |
53 | + | |
54 | + [Fact] | |
55 | + public void JsonXmlToString_SubsetTest() | |
56 | + { | |
57 | + var json = """{"hoge":{"aaa":12345}}"""; | |
58 | + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); | |
59 | + using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max); | |
60 | + var rootElement = XElement.Load(jsonReader); | |
61 | + | |
62 | + Assert.Equal("""{"aaa":12345}""", JsonUtils.JsonXmlToString(rootElement.Element("hoge"))); | |
63 | + } | |
64 | + | |
65 | + [Fact] | |
66 | + public void JsonXmlToString_NullTest() | |
67 | + { | |
68 | + var json = """{"hoge":null}"""; | |
69 | + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); | |
70 | + using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max); | |
71 | + var rootElement = XElement.Load(jsonReader); | |
72 | + | |
73 | + Assert.Equal("null", JsonUtils.JsonXmlToString(rootElement.Element("hoge"))); | |
74 | + } | |
37 | 75 | } |
38 | 76 | } |
@@ -55,6 +55,9 @@ | ||
55 | 55 | <None Update="Resources\Responses\TimelineTweet_RetweetedTweet.json"> |
56 | 56 | <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
57 | 57 | </None> |
58 | + <None Update="Resources\Responses\TimelineTweet_TweetWithVisibility.json"> | |
59 | + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |
60 | + </None> | |
58 | 61 | <None Update="Resources\Responses\TimelineTweet_TweetWithMedia.json"> |
59 | 62 | <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
60 | 63 | </None> |
@@ -0,0 +1,532 @@ | ||
1 | +{ | |
2 | + "itemType": "TimelineTweet", | |
3 | + "__typename": "TimelineTweet", | |
4 | + "tweet_results": { | |
5 | + "result": { | |
6 | + "__typename": "TweetWithVisibilityResults", | |
7 | + "tweet": { | |
8 | + "rest_id": "1602775353088524288", | |
9 | + "core": { | |
10 | + "user_results": { | |
11 | + "result": { | |
12 | + "__typename": "User", | |
13 | + "id": "VXNlcjozNTc3NTA4OTE=", | |
14 | + "rest_id": "357750891", | |
15 | + "affiliates_highlighted_label": { | |
16 | + "label": { | |
17 | + "url": { | |
18 | + "url": "https://twitter.com/Twitter", | |
19 | + "urlType": "DeepLink" | |
20 | + }, | |
21 | + "badge": { | |
22 | + "url": "https://pbs.twimg.com/profile_images/1488548719062654976/u6qfBBkF_bigger.jpg" | |
23 | + }, | |
24 | + "description": "Twitter", | |
25 | + "userLabelType": "BusinessLabel", | |
26 | + "userLabelDisplayType": "Badge" | |
27 | + } | |
28 | + }, | |
29 | + "has_graduated_access": true, | |
30 | + "is_blue_verified": true, | |
31 | + "profile_image_shape": "Square", | |
32 | + "legacy": { | |
33 | + "can_dm": false, | |
34 | + "can_media_tag": true, | |
35 | + "created_at": "Thu Aug 18 21:08:15 +0000 2011", | |
36 | + "default_profile": false, | |
37 | + "default_profile_image": false, | |
38 | + "description": "because brands are good at Twitter too", | |
39 | + "entities": { | |
40 | + "description": { | |
41 | + "urls": [] | |
42 | + }, | |
43 | + "url": { | |
44 | + "urls": [ | |
45 | + { | |
46 | + "display_url": "marketing.twitter.com", | |
47 | + "expanded_url": "https://marketing.twitter.com", | |
48 | + "url": "https://t.co/p14vvM2Vul", | |
49 | + "indices": [ | |
50 | + 0, | |
51 | + 23 | |
52 | + ] | |
53 | + } | |
54 | + ] | |
55 | + } | |
56 | + }, | |
57 | + "fast_followers_count": 0, | |
58 | + "favourites_count": 4233, | |
59 | + "followers_count": 1039062, | |
60 | + "friends_count": 826, | |
61 | + "has_custom_timelines": true, | |
62 | + "is_translator": false, | |
63 | + "listed_count": 5052, | |
64 | + "location": "Twitter HQ", | |
65 | + "media_count": 1865, | |
66 | + "name": "Twitter Marketing", | |
67 | + "normal_followers_count": 1039062, | |
68 | + "pinned_tweet_ids_str": [], | |
69 | + "possibly_sensitive": false, | |
70 | + "profile_banner_url": "https://pbs.twimg.com/profile_banners/357750891/1677173802", | |
71 | + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1628811028388610048/C8AyxJiB_normal.jpg", | |
72 | + "profile_interstitial_type": "", | |
73 | + "screen_name": "TwitterMktg", | |
74 | + "statuses_count": 10161, | |
75 | + "translator_type": "none", | |
76 | + "url": "https://t.co/p14vvM2Vul", | |
77 | + "verified": false, | |
78 | + "verified_type": "Business", | |
79 | + "want_retweets": false, | |
80 | + "withheld_in_countries": [] | |
81 | + } | |
82 | + } | |
83 | + } | |
84 | + }, | |
85 | + "card": { | |
86 | + "rest_id": "https://t.co/v4kIDVQjpy", | |
87 | + "legacy": { | |
88 | + "binding_values": [ | |
89 | + { | |
90 | + "key": "photo_image_full_size_large", | |
91 | + "value": { | |
92 | + "image_value": { | |
93 | + "height": 402, | |
94 | + "width": 768, | |
95 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=800x419" | |
96 | + }, | |
97 | + "type": "IMAGE" | |
98 | + } | |
99 | + }, | |
100 | + { | |
101 | + "key": "thumbnail_image", | |
102 | + "value": { | |
103 | + "image_value": { | |
104 | + "height": 147, | |
105 | + "width": 280, | |
106 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=280x150" | |
107 | + }, | |
108 | + "type": "IMAGE" | |
109 | + } | |
110 | + }, | |
111 | + { | |
112 | + "key": "description", | |
113 | + "value": { | |
114 | + "string_value": "We’re re-enabling Twitter Blue sign ups on iOS and web. Twitter Blue subscribers will get access to subscriber-only features* such as Edit Tweet, 1080p video uploads and reader mode.", | |
115 | + "type": "STRING" | |
116 | + } | |
117 | + }, | |
118 | + { | |
119 | + "key": "domain", | |
120 | + "value": { | |
121 | + "string_value": "blog.twitter.com", | |
122 | + "type": "STRING" | |
123 | + } | |
124 | + }, | |
125 | + { | |
126 | + "key": "thumbnail_image_large", | |
127 | + "value": { | |
128 | + "image_value": { | |
129 | + "height": 315, | |
130 | + "width": 600, | |
131 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=600x600" | |
132 | + }, | |
133 | + "type": "IMAGE" | |
134 | + } | |
135 | + }, | |
136 | + { | |
137 | + "key": "summary_photo_image_small", | |
138 | + "value": { | |
139 | + "image_value": { | |
140 | + "height": 202, | |
141 | + "width": 386, | |
142 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=386x202" | |
143 | + }, | |
144 | + "type": "IMAGE" | |
145 | + } | |
146 | + }, | |
147 | + { | |
148 | + "key": "thumbnail_image_original", | |
149 | + "value": { | |
150 | + "image_value": { | |
151 | + "height": 403, | |
152 | + "width": 768, | |
153 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=orig" | |
154 | + }, | |
155 | + "type": "IMAGE" | |
156 | + } | |
157 | + }, | |
158 | + { | |
159 | + "key": "site", | |
160 | + "value": { | |
161 | + "scribe_key": "publisher_id", | |
162 | + "type": "USER", | |
163 | + "user_value": { | |
164 | + "id_str": "783214", | |
165 | + "path": [] | |
166 | + } | |
167 | + } | |
168 | + }, | |
169 | + { | |
170 | + "key": "photo_image_full_size_small", | |
171 | + "value": { | |
172 | + "image_value": { | |
173 | + "height": 202, | |
174 | + "width": 386, | |
175 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=386x202" | |
176 | + }, | |
177 | + "type": "IMAGE" | |
178 | + } | |
179 | + }, | |
180 | + { | |
181 | + "key": "summary_photo_image_large", | |
182 | + "value": { | |
183 | + "image_value": { | |
184 | + "height": 402, | |
185 | + "width": 768, | |
186 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=800x419" | |
187 | + }, | |
188 | + "type": "IMAGE" | |
189 | + } | |
190 | + }, | |
191 | + { | |
192 | + "key": "thumbnail_image_small", | |
193 | + "value": { | |
194 | + "image_value": { | |
195 | + "height": 76, | |
196 | + "width": 144, | |
197 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=144x144" | |
198 | + }, | |
199 | + "type": "IMAGE" | |
200 | + } | |
201 | + }, | |
202 | + { | |
203 | + "key": "thumbnail_image_x_large", | |
204 | + "value": { | |
205 | + "image_value": { | |
206 | + "height": 403, | |
207 | + "width": 768, | |
208 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=png&name=2048x2048_2_exp" | |
209 | + }, | |
210 | + "type": "IMAGE" | |
211 | + } | |
212 | + }, | |
213 | + { | |
214 | + "key": "photo_image_full_size_original", | |
215 | + "value": { | |
216 | + "image_value": { | |
217 | + "height": 403, | |
218 | + "width": 768, | |
219 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=orig" | |
220 | + }, | |
221 | + "type": "IMAGE" | |
222 | + } | |
223 | + }, | |
224 | + { | |
225 | + "key": "vanity_url", | |
226 | + "value": { | |
227 | + "scribe_key": "vanity_url", | |
228 | + "string_value": "blog.twitter.com", | |
229 | + "type": "STRING" | |
230 | + } | |
231 | + }, | |
232 | + { | |
233 | + "key": "photo_image_full_size", | |
234 | + "value": { | |
235 | + "image_value": { | |
236 | + "height": 314, | |
237 | + "width": 600, | |
238 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=600x314" | |
239 | + }, | |
240 | + "type": "IMAGE" | |
241 | + } | |
242 | + }, | |
243 | + { | |
244 | + "key": "thumbnail_image_color", | |
245 | + "value": { | |
246 | + "image_color_value": { | |
247 | + "palette": [ | |
248 | + { | |
249 | + "rgb": { | |
250 | + "blue": 243, | |
251 | + "green": 172, | |
252 | + "red": 69 | |
253 | + }, | |
254 | + "percentage": 100 | |
255 | + } | |
256 | + ] | |
257 | + }, | |
258 | + "type": "IMAGE_COLOR" | |
259 | + } | |
260 | + }, | |
261 | + { | |
262 | + "key": "title", | |
263 | + "value": { | |
264 | + "string_value": "Twitter Blue is back. And gold checkmarks are here!", | |
265 | + "type": "STRING" | |
266 | + } | |
267 | + }, | |
268 | + { | |
269 | + "key": "summary_photo_image_color", | |
270 | + "value": { | |
271 | + "image_color_value": { | |
272 | + "palette": [ | |
273 | + { | |
274 | + "rgb": { | |
275 | + "blue": 243, | |
276 | + "green": 172, | |
277 | + "red": 69 | |
278 | + }, | |
279 | + "percentage": 100 | |
280 | + } | |
281 | + ] | |
282 | + }, | |
283 | + "type": "IMAGE_COLOR" | |
284 | + } | |
285 | + }, | |
286 | + { | |
287 | + "key": "summary_photo_image_x_large", | |
288 | + "value": { | |
289 | + "image_value": { | |
290 | + "height": 403, | |
291 | + "width": 768, | |
292 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=png&name=2048x2048_2_exp" | |
293 | + }, | |
294 | + "type": "IMAGE" | |
295 | + } | |
296 | + }, | |
297 | + { | |
298 | + "key": "summary_photo_image", | |
299 | + "value": { | |
300 | + "image_value": { | |
301 | + "height": 314, | |
302 | + "width": 600, | |
303 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=600x314" | |
304 | + }, | |
305 | + "type": "IMAGE" | |
306 | + } | |
307 | + }, | |
308 | + { | |
309 | + "key": "photo_image_full_size_color", | |
310 | + "value": { | |
311 | + "image_color_value": { | |
312 | + "palette": [ | |
313 | + { | |
314 | + "rgb": { | |
315 | + "blue": 243, | |
316 | + "green": 172, | |
317 | + "red": 69 | |
318 | + }, | |
319 | + "percentage": 100 | |
320 | + } | |
321 | + ] | |
322 | + }, | |
323 | + "type": "IMAGE_COLOR" | |
324 | + } | |
325 | + }, | |
326 | + { | |
327 | + "key": "photo_image_full_size_x_large", | |
328 | + "value": { | |
329 | + "image_value": { | |
330 | + "height": 403, | |
331 | + "width": 768, | |
332 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=png&name=2048x2048_2_exp" | |
333 | + }, | |
334 | + "type": "IMAGE" | |
335 | + } | |
336 | + }, | |
337 | + { | |
338 | + "key": "card_url", | |
339 | + "value": { | |
340 | + "scribe_key": "card_url", | |
341 | + "string_value": "https://t.co/v4kIDVQjpy", | |
342 | + "type": "STRING" | |
343 | + } | |
344 | + }, | |
345 | + { | |
346 | + "key": "summary_photo_image_original", | |
347 | + "value": { | |
348 | + "image_value": { | |
349 | + "height": 403, | |
350 | + "width": 768, | |
351 | + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=orig" | |
352 | + }, | |
353 | + "type": "IMAGE" | |
354 | + } | |
355 | + } | |
356 | + ], | |
357 | + "card_platform": { | |
358 | + "platform": { | |
359 | + "audience": { | |
360 | + "name": "production" | |
361 | + }, | |
362 | + "device": { | |
363 | + "name": "Swift", | |
364 | + "version": "12" | |
365 | + } | |
366 | + } | |
367 | + }, | |
368 | + "name": "summary_large_image", | |
369 | + "url": "https://t.co/v4kIDVQjpy", | |
370 | + "user_refs_results": [ | |
371 | + { | |
372 | + "result": { | |
373 | + "__typename": "User", | |
374 | + "id": "VXNlcjo3ODMyMTQ=", | |
375 | + "rest_id": "783214", | |
376 | + "affiliates_highlighted_label": {}, | |
377 | + "has_graduated_access": true, | |
378 | + "is_blue_verified": true, | |
379 | + "profile_image_shape": "Square", | |
380 | + "legacy": { | |
381 | + "can_dm": false, | |
382 | + "can_media_tag": true, | |
383 | + "created_at": "Tue Feb 20 14:35:54 +0000 2007", | |
384 | + "default_profile": false, | |
385 | + "default_profile_image": false, | |
386 | + "description": "What's happening?!", | |
387 | + "entities": { | |
388 | + "description": { | |
389 | + "urls": [] | |
390 | + }, | |
391 | + "url": { | |
392 | + "urls": [ | |
393 | + { | |
394 | + "display_url": "about.twitter.com", | |
395 | + "expanded_url": "https://about.twitter.com/", | |
396 | + "url": "https://t.co/DAtOo6uuHk", | |
397 | + "indices": [ | |
398 | + 0, | |
399 | + 23 | |
400 | + ] | |
401 | + } | |
402 | + ] | |
403 | + } | |
404 | + }, | |
405 | + "fast_followers_count": 0, | |
406 | + "favourites_count": 6118, | |
407 | + "followers_count": 65674140, | |
408 | + "friends_count": 0, | |
409 | + "has_custom_timelines": true, | |
410 | + "is_translator": false, | |
411 | + "listed_count": 88108, | |
412 | + "location": "everywhere", | |
413 | + "media_count": 2445, | |
414 | + "name": "Twitter", | |
415 | + "normal_followers_count": 65674140, | |
416 | + "pinned_tweet_ids_str": [], | |
417 | + "possibly_sensitive": false, | |
418 | + "profile_banner_url": "https://pbs.twimg.com/profile_banners/783214/1646075315", | |
419 | + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1488548719062654976/u6qfBBkF_normal.jpg", | |
420 | + "profile_interstitial_type": "", | |
421 | + "screen_name": "Twitter", | |
422 | + "statuses_count": 15052, | |
423 | + "translator_type": "regular", | |
424 | + "url": "https://t.co/DAtOo6uuHk", | |
425 | + "verified": false, | |
426 | + "verified_type": "Business", | |
427 | + "want_retweets": false, | |
428 | + "withheld_in_countries": [] | |
429 | + } | |
430 | + } | |
431 | + } | |
432 | + ] | |
433 | + } | |
434 | + }, | |
435 | + "unified_card": { | |
436 | + "card_fetch_state": "NoCard" | |
437 | + }, | |
438 | + "edit_control": { | |
439 | + "edit_tweet_ids": [ | |
440 | + "1602775353088524288" | |
441 | + ], | |
442 | + "editable_until_msecs": "1670968196000", | |
443 | + "is_edit_eligible": true, | |
444 | + "edits_remaining": "5" | |
445 | + }, | |
446 | + "edit_perspective": { | |
447 | + "favorited": false, | |
448 | + "retweeted": false | |
449 | + }, | |
450 | + "is_translatable": false, | |
451 | + "views": { | |
452 | + "state": "Enabled" | |
453 | + }, | |
454 | + "source": "<a href=\"https://mobile.twitter.com\" rel=\"nofollow\">Twitter Web App</a>", | |
455 | + "legacy": { | |
456 | + "bookmark_count": 6, | |
457 | + "bookmarked": false, | |
458 | + "created_at": "Tue Dec 13 21:19:56 +0000 2022", | |
459 | + "conversation_control": { | |
460 | + "policy": "Community", | |
461 | + "conversation_owner_results": { | |
462 | + "result": { | |
463 | + "__typename": "User", | |
464 | + "legacy": { | |
465 | + "screen_name": "TwitterMktg" | |
466 | + } | |
467 | + } | |
468 | + } | |
469 | + }, | |
470 | + "conversation_id_str": "1602775353088524288", | |
471 | + "display_text_range": [ | |
472 | + 0, | |
473 | + 110 | |
474 | + ], | |
475 | + "entities": { | |
476 | + "user_mentions": [], | |
477 | + "urls": [ | |
478 | + { | |
479 | + "display_url": "blog.twitter.com/en_us/topics/p…", | |
480 | + "expanded_url": "https://blog.twitter.com/en_us/topics/product/2022/twitter-blue-update", | |
481 | + "url": "https://t.co/v4kIDVQjpy", | |
482 | + "indices": [ | |
483 | + 87, | |
484 | + 110 | |
485 | + ] | |
486 | + } | |
487 | + ], | |
488 | + "hashtags": [], | |
489 | + "symbols": [] | |
490 | + }, | |
491 | + "favorite_count": 201, | |
492 | + "favorited": false, | |
493 | + "full_text": "Twitter Blue is back. And Gold Checkmarks for advertisers are here! Read the latest: \nhttps://t.co/v4kIDVQjpy", | |
494 | + "is_quote_status": false, | |
495 | + "lang": "en", | |
496 | + "limited_actions": "limited_replies", | |
497 | + "possibly_sensitive": false, | |
498 | + "possibly_sensitive_editable": true, | |
499 | + "quote_count": 36, | |
500 | + "reply_count": 0, | |
501 | + "retweet_count": 40, | |
502 | + "retweeted": false, | |
503 | + "user_id_str": "357750891", | |
504 | + "id_str": "1602775353088524288" | |
505 | + }, | |
506 | + "quick_promote_eligibility": { | |
507 | + "eligibility": "IneligibleNotProfessional" | |
508 | + } | |
509 | + }, | |
510 | + "limitedActionResults": { | |
511 | + "limited_actions": [ | |
512 | + { | |
513 | + "action": "Reply", | |
514 | + "prompt": { | |
515 | + "__typename": "CtaLimitedActionPrompt", | |
516 | + "cta_type": "SeeConversation", | |
517 | + "headline": { | |
518 | + "text": "Who can reply?", | |
519 | + "entities": [] | |
520 | + }, | |
521 | + "subtext": { | |
522 | + "text": "People the author mentioned can reply", | |
523 | + "entities": [] | |
524 | + } | |
525 | + } | |
526 | + } | |
527 | + ] | |
528 | + } | |
529 | + } | |
530 | + }, | |
531 | + "tweetDisplayType": "Tweet" | |
532 | +} |
@@ -23,6 +23,7 @@ | ||
23 | 23 | |
24 | 24 | using System; |
25 | 25 | using System.Collections.Generic; |
26 | +using System.IO; | |
26 | 27 | using System.Linq; |
27 | 28 | using System.Runtime.Serialization.Json; |
28 | 29 | using System.Text; |
@@ -82,9 +83,18 @@ namespace OpenTween.Api.GraphQL | ||
82 | 83 | var param = this.CreateParameters(); |
83 | 84 | using var stream = await apiConnection.GetStreamAsync(EndpointUri, param); |
84 | 85 | using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max); |
85 | - var xElm = XElement.Load(jsonReader); | |
86 | 86 | |
87 | - return TimelineTweet.ExtractTimelineTweets(xElm); | |
87 | + XElement rootElm; | |
88 | + try | |
89 | + { | |
90 | + rootElm = XElement.Load(jsonReader); | |
91 | + } | |
92 | + catch (IOException ex) | |
93 | + { | |
94 | + throw new WebApiException("IO Error", ex); | |
95 | + } | |
96 | + | |
97 | + return TimelineTweet.ExtractTimelineTweets(rootElm); | |
88 | 98 | } |
89 | 99 | } |
90 | 100 | } |
@@ -49,8 +49,24 @@ namespace OpenTween.Api.GraphQL | ||
49 | 49 | |
50 | 50 | public TwitterStatus ToTwitterStatus() |
51 | 51 | { |
52 | - var tweetElm = this.Element.Element("tweet_results")?.Element("result") ?? throw CreateParseError(); | |
53 | - return this.ParseTweet(tweetElm); | |
52 | + try | |
53 | + { | |
54 | + var resultElm = this.Element.Element("tweet_results")?.Element("result") ?? throw CreateParseError(); | |
55 | + var tweetElm = resultElm.Element("__typename")?.Value switch | |
56 | + { | |
57 | + "Tweet" => resultElm, | |
58 | + "TweetWithVisibilityResults" => resultElm.Element("tweet") ?? throw CreateParseError(), | |
59 | + _ => throw CreateParseError(), | |
60 | + }; | |
61 | + | |
62 | + return this.ParseTweet(tweetElm); | |
63 | + } | |
64 | + catch (WebApiException ex) | |
65 | + { | |
66 | + ex.ResponseText = JsonUtils.JsonXmlToString(this.Element); | |
67 | + MyCommon.TraceOut(ex); | |
68 | + throw; | |
69 | + } | |
54 | 70 | } |
55 | 71 | |
56 | 72 | private TwitterStatus ParseTweet(XElement tweetElm) |
@@ -21,7 +21,10 @@ | ||
21 | 21 | |
22 | 22 | #nullable enable |
23 | 23 | |
24 | +using System.IO; | |
25 | +using System.Runtime.Serialization.Json; | |
24 | 26 | using System.Text; |
27 | +using System.Xml.Linq; | |
25 | 28 | |
26 | 29 | namespace OpenTween.Api |
27 | 30 | { |
@@ -44,5 +47,31 @@ namespace OpenTween.Api | ||
44 | 47 | |
45 | 48 | return builder.ToString(); |
46 | 49 | } |
50 | + | |
51 | + /// <summary> | |
52 | + /// <see cref="JsonReaderWriterFactory"/>で読み込んだ<see cref="XElement"/>をJSONとして書き出す | |
53 | + /// </summary> | |
54 | + public static string JsonXmlToString(XElement element) | |
55 | + { | |
56 | + var isRoot = element.Name == "root"; | |
57 | + | |
58 | + using var stream = new MemoryStream(); | |
59 | + using (var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream)) | |
60 | + { | |
61 | + if (isRoot) | |
62 | + { | |
63 | + element.WriteTo(jsonWriter); | |
64 | + } | |
65 | + else | |
66 | + { | |
67 | + jsonWriter.WriteStartElement("root"); | |
68 | + jsonWriter.WriteAttributeString("type", element.Attribute("type").Value); | |
69 | + foreach (var child in element.Elements()) | |
70 | + child.WriteTo(jsonWriter); | |
71 | + jsonWriter.WriteEndElement(); | |
72 | + } | |
73 | + } | |
74 | + return Encoding.UTF8.GetString(stream.ToArray()); | |
75 | + } | |
47 | 76 | } |
48 | 77 | } |
@@ -75,6 +75,8 @@ namespace OpenTween.Models | ||
75 | 75 | var originalStatus = retweetedStatus ?? status; |
76 | 76 | var originalStatusUser = originalStatus.User ?? TwitterUser.CreateUnknownUser(); |
77 | 77 | |
78 | + var isMe = statusUser.Id == selfUserId; | |
79 | + | |
78 | 80 | bool isFav = favTweet; |
79 | 81 | if (isFav == false) |
80 | 82 | { |
@@ -131,7 +133,7 @@ namespace OpenTween.Models | ||
131 | 133 | var (sourceText, sourceUri) = ParseSource(originalStatus.Source); |
132 | 134 | |
133 | 135 | var isOwl = false; |
134 | - if (followerIds.Count > 0) | |
136 | + if (!isMe && followerIds.Count > 0) | |
135 | 137 | isOwl = !followerIds.Contains(originalStatusUser.Id); |
136 | 138 | |
137 | 139 | var createdAtForSorting = ParseDateTimeFromSnowflakeId(status.Id, status.CreatedAt); |
@@ -144,7 +146,7 @@ namespace OpenTween.Models | ||
144 | 146 | // status から生成 |
145 | 147 | StatusId = new TwitterStatusId(status.IdStr), |
146 | 148 | CreatedAtForSorting = createdAtForSorting, |
147 | - IsMe = statusUser.Id == selfUserId, | |
149 | + IsMe = isMe, | |
148 | 150 | |
149 | 151 | // originalStatus から生成 |
150 | 152 | CreatedAt = createdAt, |
@@ -159,7 +161,7 @@ namespace OpenTween.Models | ||
159 | 161 | Source = string.Intern(sourceText), |
160 | 162 | SourceUri = sourceUri, |
161 | 163 | IsFav = isFav, |
162 | - IsReply = retweetedStatus != null && replyToList.Any(x => x.UserId == selfUserId), | |
164 | + IsReply = retweetedStatus == null && replyToList.Any(x => x.UserId == selfUserId), | |
163 | 165 | InReplyToStatusId = originalStatus.InReplyToStatusIdStr != null ? new TwitterStatusId(originalStatus.InReplyToStatusIdStr) : null, |
164 | 166 | InReplyToUser = originalStatus.InReplyToScreenName, |
165 | 167 | InReplyToUserId = originalStatus.InReplyToUserId, |
@@ -22,7 +22,7 @@ using System.Runtime.InteropServices; | ||
22 | 22 | // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です |
23 | 23 | [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] |
24 | 24 | |
25 | -[assembly: AssemblyVersion("3.6.0.0")] | |
25 | +[assembly: AssemblyVersion("3.6.1.0")] | |
26 | 26 | |
27 | 27 | [assembly: InternalsVisibleTo("OpenTween.Tests")] |
28 | 28 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq |
@@ -580,20 +580,17 @@ namespace OpenTween.Properties { | ||
580 | 580 | /// <summary> |
581 | 581 | /// 更新履歴 |
582 | 582 | /// |
583 | + ///==== Ver 3.6.1(2023/07/07) | |
584 | + /// * CHG: graphqlエンドポイントからのレスポンスの読み込み失敗時に問題の起きたツイートをErrorLogsに書き出す機能を追加 | |
585 | + /// * FIX: リプライ制限されたツイートがリストのタイムラインに含まれているとエラーになる不具合を修正 (thx @wal_san!) | |
586 | + /// * FIX: 発言一覧で自分のツイートが片思い状態の色で描画される不具合を修正 | |
587 | + /// * FIX: 「ユーザー定義のURL」が未設定の状態で「ユーザー定義のURL」を開く操作をするとエラーが発生する不具合を修正 (thx @Tan90909090!) | |
588 | + /// * FIX: graphqlエンドポイントからのレスポンス読み込み中に発生した接続エラーが適切に処理されない不具合を修正 | |
589 | + /// * FIX: Replyタブにリプライが表示されない不具合を修正 | |
590 | + /// | |
583 | 591 | ///==== Ver 3.6.0(2023/07/05) |
584 | 592 | /// * NEW: Cookie使用時にgraphqlエンドポイントを使用したリストのタイムライン取得に対応 |
585 | - /// * FIX: 「このタブの発言をクリア」で参照されなくなった発言分のメモリが開放されない場合がある不具合を修正 | |
586 | - /// | |
587 | - ///==== Ver 3.5.0(2023/06/16) | |
588 | - /// * CHG: アカウント追加時にOpenTweenのAPIキーによる認可を選択肢に追加 | |
589 | - /// * CHG: 非対応のOSを使用している場合に起動時に警告を表示する | |
590 | - /// * FIX: 削除したタブの取消時に同名のタブが存在した場合のエラーが適切に処理されない不具合を修正 | |
591 | - /// * FIX: 発言一覧のアイコン画像の取得に失敗した場合のエラーが適切に処理されない不具合を修正 | |
592 | - /// * FIX: Cookieを使用する場合にUserTimelineで99件を超えて取得するとエラーが返る問題の回避策を追加 | |
593 | - /// | |
594 | - ///==== Ver 3.4.0(2023/01/29) | |
595 | - /// * NEW: 複数枚の画像を添付する際に画像の削除や順序の変更ができるようになりました | |
596 | - /// * FIX: [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 | |
593 | + /// * FIX: 「このタブの発言をクリア」で参照され [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 | |
597 | 594 | /// </summary> |
598 | 595 | internal static string ChangeLog { |
599 | 596 | get { |
@@ -1,5 +1,13 @@ | ||
1 | 1 | 更新履歴 |
2 | 2 | |
3 | +==== Ver 3.6.1(2023/07/07) | |
4 | + * CHG: graphqlエンドポイントからのレスポンスの読み込み失敗時に問題の起きたツイートをErrorLogsに書き出す機能を追加 | |
5 | + * FIX: リプライ制限されたツイートがリストのタイムラインに含まれているとエラーになる不具合を修正 (thx @wal_san!) | |
6 | + * FIX: 発言一覧で自分のツイートが片思い状態の色で描画される不具合を修正 | |
7 | + * FIX: 「ユーザー定義のURL」が未設定の状態で「ユーザー定義のURL」を開く操作をするとエラーが発生する不具合を修正 (thx @Tan90909090!) | |
8 | + * FIX: graphqlエンドポイントからのレスポンス読み込み中に発生した接続エラーが適切に処理されない不具合を修正 | |
9 | + * FIX: Replyタブにリプライが表示されない不具合を修正 | |
10 | + | |
3 | 11 | ==== Ver 3.6.0(2023/07/05) |
4 | 12 | * NEW: Cookie使用時にgraphqlエンドポイントを使用したリストのタイムライン取得に対応 |
5 | 13 | * FIX: 「このタブの発言をクリア」で参照されなくなった発言分のメモリが開放されない場合がある不具合を修正 |
@@ -9444,7 +9444,7 @@ namespace OpenTween | ||
9444 | 9444 | |
9445 | 9445 | private async Task OpenUserAppointUrl() |
9446 | 9446 | { |
9447 | - if (this.settings.Common.UserAppointUrl != null) | |
9447 | + if (!MyCommon.IsNullOrEmpty(this.settings.Common.UserAppointUrl)) | |
9448 | 9448 | { |
9449 | 9449 | if (this.settings.Common.UserAppointUrl.Contains("{ID}") || this.settings.Common.UserAppointUrl.Contains("{STATUS}")) |
9450 | 9450 | { |
@@ -35,7 +35,7 @@ namespace OpenTween | ||
35 | 35 | [Serializable] |
36 | 36 | public class WebApiException : Exception |
37 | 37 | { |
38 | - public string? ResponseText { get; } = null; | |
38 | + public string? ResponseText { get; set; } = null; | |
39 | 39 | |
40 | 40 | public WebApiException() |
41 | 41 | { |
@@ -1,4 +1,4 @@ | ||
1 | -version: 3.5.0.{build} | |
1 | +version: 3.6.0.{build} | |
2 | 2 | |
3 | 3 | os: Visual Studio 2022 |
4 | 4 |