OSDN Git Service

Merge pull request #307 from opentween/detect-rate-limits
[opentween/open-tween.git] / OpenTween / Api / GraphQL / TimelineResponseParser.cs
diff --git a/OpenTween/Api/GraphQL/TimelineResponseParser.cs b/OpenTween/Api/GraphQL/TimelineResponseParser.cs
new file mode 100644 (file)
index 0000000..8fe315f
--- /dev/null
@@ -0,0 +1,45 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2024 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#nullable enable
+
+using System.Xml.Linq;
+using System.Xml.XPath;
+
+namespace OpenTween.Api.GraphQL
+{
+    public class TimelineResponseParser
+    {
+        public static TimelineResponse Parse(XElement rootElm)
+        {
+            ErrorResponse.ThrowIfError(rootElm);
+
+            var tweets = TimelineTweet.ExtractTimelineTweets(rootElm);
+            if (tweets.Length == 0)
+                ErrorResponse.ThrowIfContainsRateLimitMessage(rootElm);
+
+            var cursorTop = rootElm.XPathSelectElement("//content[__typename[text()='TimelineTimelineCursor']][cursorType[text()='Top']]/value")?.Value;
+            var cursorBottom = rootElm.XPathSelectElement("//content[__typename[text()='TimelineTimelineCursor']][cursorType[text()='Bottom']]/value")?.Value;
+
+            return new(tweets, cursorTop, cursorBottom);
+        }
+    }
+}