Просмотр исходного кода

Support promo_video_website cards

Zed 7 лет назад
Родитель
Сommit
27cf4cdf64
6 измененных файлов с 48 добавлено и 35 удалено
  1. 6 1
      public/style.css
  2. 5 1
      src/api.nim
  3. 1 16
      src/parser.nim
  4. 11 3
      src/parserutils.nim
  5. 8 2
      src/types.nim
  6. 17 12
      src/views/tweet.nim

+ 6 - 1
public/style.css

@@ -237,7 +237,7 @@ nav {
 
 .gallery-row .attachment:last-child, .gallery-row .attachments:last-child, .video-container {
     margin: 0;
-    max-height: 500px;
+    max-height: 530px;
 }
 
 .attachments .attachment {
@@ -901,6 +901,11 @@ video {
     border-color: #808080;
 }
 
+.card-container .attachments {
+    margin: 0;
+    border-radius: 0;
+}
+
 .large .card-container {
     display: block;
 }

+ 5 - 1
src/api.nim

@@ -106,7 +106,11 @@ proc getVideo*(tweet: Tweet; token: string) {.async.} =
     await getVideo(tweet, guestToken)
     return
 
-  tweet.video = some(parseVideo(json))
+  if tweet.card.isNone:
+    tweet.video = some(parseVideo(json))
+  else:
+    get(tweet.card).video = some(parseVideo(json))
+    tweet.video = none(Video)
   tokenUses.inc
 
 proc getVideos*(thread: Thread; token="") {.async.} =

+ 1 - 16
src/parser.nim

@@ -180,19 +180,6 @@ proc parsePhotoRail*(node: XmlNode): seq[GalleryPhoto] =
     )
 
 proc parseCard*(card: var Card; node: XmlNode) =
-  let cardKind = node.select("head > meta[name*=card_name]").attr("content")
-
-  if "summary_large_image" in cardKind:
-    card.kind = summaryLarge
-  elif "summary" in cardKind:
-    card.kind = summary
-  elif "live_event" in cardKind:
-    card.kind = liveEvent
-  elif "player" in cardKind:
-    card.kind = player
-  elif "promo_website" in cardKind:
-    card.kind = promoWebsite
-
   card.title = node.selectText("h2.TwitterCard-title")
   card.text = node.selectText("p.tcu-resetMargin")
   card.dest = node.selectText("span.SummaryCard-destination")
@@ -203,9 +190,7 @@ proc parseCard*(card: var Card; node: XmlNode) =
   let image = node.select(".tcu-imageWrapper img")
   if image != nil:
     # workaround for issue 11713
-    card.image = image.attr("data-src").replace("gname", "g&name")
-  else:
-    echo card.id
+    card.image = some(image.attr("data-src").replace("gname", "g&name"))
 
   if card.kind == liveEvent:
     card.text = card.title

+ 11 - 3
src/parserutils.nim

@@ -1,4 +1,4 @@
-import xmltree, htmlparser, strtabs, strformat, times
+import xmltree, htmlparser, strtabs, strformat, strutils, times
 import regex
 
 import types, formatters, api
@@ -169,13 +169,16 @@ proc getQuoteMedia*(quote: var Quote; node: XmlNode) =
 
 proc getTweetCard*(tweet: Tweet; node: XmlNode) =
   if node.attr("data-has-cards") == "false": return
-  let cardType = node.attr("data-card2-type")
+  var cardType = node.attr("data-card2-type")
+
+  if ":" in cardType:
+    cardType = cardType.split(":")[^1]
 
   if "poll" in cardType:
     tweet.poll = some(Poll())
     return
 
-  let cardDiv = node.select(".card2 > div")
+  let cardDiv = node.select(".card2 > .js-macaw-cards-iframe-container")
   if cardDiv == nil: return
 
   var card = Card(
@@ -183,6 +186,11 @@ proc getTweetCard*(tweet: Tweet; node: XmlNode) =
     query: cardDiv.attr("data-src")
   )
 
+  try:
+    card.kind = parseEnum[CardKind](cardType)
+  except ValueError:
+    card.kind = summary
+
   let cardUrl = cardDiv.attr("data-card-url")
   for n in node.selectAll(".tweet-text a"):
     if n.attr("href") == cardUrl:

+ 8 - 2
src/types.nim

@@ -71,7 +71,12 @@ type
     leader*: int
 
   CardKind* = enum
-    summary, summaryLarge, liveEvent, player, promoWebsite
+    summary = "summary"
+    summaryLarge = "summary_large_image"
+    promoWebsite = "promo_website"
+    promoVideo = "promo_video_website"
+    player = "player"
+    liveEvent = "live_event"
 
   Card* = object
     kind*: CardKind
@@ -81,7 +86,8 @@ type
     title*: string
     dest*: string
     text*: string
-    image*: string
+    image*: Option[string]
+    video*: Option[Video]
 
   Quote* = object
     id*: string

+ 17 - 12
src/views/tweet.nim

@@ -77,20 +77,25 @@ proc renderPoll(poll: Poll): VNode =
     span(class="poll-info"):
       text $poll.votes & " votes • " & poll.status
 
+proc renderCardImage(card: Card): VNode =
+  buildHtml(tdiv(class="card-image-container")):
+    tdiv(class="card-image"):
+      img(src=get(card.image).getSigUrl("pic"))
+      if card.kind == player:
+        tdiv(class="card-overlay"):
+          tdiv(class="card-overlay-circle"):
+            span(class="card-overlay-triangle")
+
 proc renderCard(card: Card): VNode =
-  const largeCards = {summaryLarge, liveEvent, promoWebsite}
+  const largeCards = {summaryLarge, liveEvent, promoWebsite, promoVideo}
   let large = if card.kind in largeCards: " large" else: ""
 
   buildHtml(tdiv(class=("card" & large))):
     a(class="card-container", href=card.url):
-      if card.image.len > 0:
-        tdiv(class="card-image-container"):
-          tdiv(class="card-image"):
-            img(src=card.image.getSigUrl("pic"))
-            if card.kind == player:
-              tdiv(class="card-overlay"):
-                tdiv(class="card-overlay-circle"):
-                  span(class="card-overlay-triangle")
+      if card.image.isSome:
+        renderCardImage(card)
+      elif card.video.isSome:
+        renderVideo(get(card.video))
 
       tdiv(class="card-content-container"):
         tdiv(class="card-content"):
@@ -181,7 +186,9 @@ proc renderTweet*(tweet: Tweet; class=""; index=0; total=(-1); last=false): VNod
         if tweet.quote.isSome:
           renderQuote(tweet.quote.get())
 
-        if tweet.photos.len > 0:
+        if tweet.card.isSome:
+          renderCard(tweet.card.get())
+        elif tweet.photos.len > 0:
           renderAlbum(tweet)
         elif tweet.video.isSome:
           renderVideo(tweet.video.get())
@@ -189,8 +196,6 @@ proc renderTweet*(tweet: Tweet; class=""; index=0; total=(-1); last=false): VNod
           renderGif(tweet.gif.get())
         elif tweet.poll.isSome:
           renderPoll(tweet.poll.get())
-        elif tweet.card.isSome:
-          renderCard(tweet.card.get())
 
         renderStats(tweet.stats)