소스 검색

Show reasons for tweets being withheld

Fixes #33
Zed 7 년 전
부모
커밋
9ff3ba2005
5개의 변경된 파일30개의 추가작업 그리고 7개의 파일을 삭제
  1. 3 0
      src/formatters.nim
  2. 12 3
      src/parser.nim
  3. 4 1
      src/routes/timeline.nim
  4. 3 1
      src/types.nim
  5. 8 2
      src/views/tweet.nim

+ 3 - 0
src/formatters.nim

@@ -107,3 +107,6 @@ proc getTime*(tweet: Tweet): string =
 
 proc getLink*(tweet: Tweet | Quote): string =
   &"/{tweet.profile.username}/status/{tweet.id}"
+
+proc getTombstone*(text: string): string =
+  text.replace(re"\n* *Learn more", "").stripText().strip(chars={' ', '\n'})

+ 12 - 3
src/parser.nim

@@ -78,8 +78,11 @@ proc parseQuote*(quote: XmlNode): Quote =
   result.getQuoteMedia(quote)
 
 proc parseTweet*(node: XmlNode): Tweet =
+  if "withheld" in node.attr("class"):
+    return Tweet(tombstone: getTombstone(node.selectText(".Tombstone-label")))
+
   let tweet = node.select(".tweet")
-  if tweet == nil or "withheld-tweet" in tweet.attr("class"):
+  if tweet == nil:
     return Tweet()
 
   result = Tweet(
@@ -113,7 +116,8 @@ proc parseTweet*(node: XmlNode): Tweet =
   let tombstone = tweet.select(".Tombstone")
   if tombstone != nil:
     if "unavailable" in tombstone.innerText():
-      result.quote = some(Quote())
+      let quote = Quote(tombstone: getTombstone(node.selectText(".Tombstone-label")))
+      result.quote = some(quote)
 
 proc parseThread*(nodes: XmlNode): Thread =
   if nodes == nil: return
@@ -128,8 +132,13 @@ proc parseThread*(nodes: XmlNode): Thread =
       result.content.add parseTweet(n)
 
 proc parseConversation*(node: XmlNode): Conversation =
+  let tweet = node.select(".permalink-tweet-container")
+
+  if tweet == nil:
+    return Conversation(tweet: parseTweet(node.select(".permalink-tweet-withheld")))
+
   result = Conversation(
-    tweet:  parseTweet(node.select(".permalink-tweet-container")),
+    tweet:  parseTweet(tweet),
     before: parseThread(node.select(".in-reply-to .stream-items"))
   )
 

+ 4 - 1
src/routes/timeline.nim

@@ -100,7 +100,10 @@ proc createTimelineRouter*(cfg: Config) =
 
       let conversation = await getTweet(@"name", @"id", getAgent())
       if conversation == nil or conversation.tweet.id.len == 0:
-        resp Http404, showError("Tweet not found", cfg.title)
+        if conversation.tweet.tombstone.len > 0:
+          resp Http404, showError(conversation.tweet.tombstone, cfg.title)
+        else:
+          resp Http404, showError("Tweet not found", cfg.title)
 
       let path = getPath()
       let title = pageTitle(conversation.tweet.profile)

+ 3 - 1
src/types.nim

@@ -118,6 +118,7 @@ type
     hasThread*: bool
     sensitive*: bool
     available*: bool
+    tombstone*: string
     thumb*: string
     badge*: string
 
@@ -139,8 +140,9 @@ type
     shortTime*: string
     reply*: seq[string]
     pinned*: bool
-    available*: bool
     hasThread*: bool
+    available*: bool
+    tombstone*: string
     stats*: TweetStats
     retweet*: Option[Retweet]
     quote*: Option[Quote]

+ 8 - 2
src/views/tweet.nim

@@ -191,7 +191,10 @@ proc renderQuote(quote: Quote; prefs: Prefs): VNode =
   if not quote.available:
     return buildHtml(tdiv(class="quote unavailable")):
       tdiv(class="unavailable-quote"):
-        text "This tweet is unavailable"
+        if quote.tombstone.len > 0:
+          text quote.tombstone
+        else:
+          text "This tweet is unavailable"
 
   buildHtml(tdiv(class="quote")):
     a(class="quote-link", href=getLink(quote))
@@ -223,7 +226,10 @@ proc renderTweet*(tweet: Tweet; prefs: Prefs; path: string; class="";
     return buildHtml(tdiv(class=divClass)):
       tdiv(class="status-el unavailable"):
         tdiv(class="unavailable-box"):
-          text "This tweet is unavailable"
+          if tweet.tombstone.len > 0:
+            text tweet.tombstone
+          else:
+            text "This tweet is unavailable"
 
   buildHtml(tdiv(class=divClass)):
     tdiv(class="status-el"):