From 27cf4cdf64c86f0a3d42d904a05cfce559d2a706 Mon Sep 17 00:00:00 2001 From: Zed Date: Mon, 15 Jul 2019 16:03:01 +0200 Subject: [PATCH] Support promo_video_website cards --- public/style.css | 7 ++++++- src/api.nim | 6 +++++- src/parser.nim | 17 +---------------- src/parserutils.nim | 14 +++++++++++--- src/types.nim | 10 ++++++++-- src/views/tweet.nim | 29 +++++++++++++++++------------ 6 files changed, 48 insertions(+), 35 deletions(-) diff --git a/public/style.css b/public/style.css index 472ed7d..df421de 100644 --- a/public/style.css +++ b/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; } diff --git a/src/api.nim b/src/api.nim index 7ec3626..9106414 100644 --- a/src/api.nim +++ b/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.} = diff --git a/src/parser.nim b/src/parser.nim index 07dd458..db8f654 100644 --- a/src/parser.nim +++ b/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 diff --git a/src/parserutils.nim b/src/parserutils.nim index 25e0b5d..a75400e 100644 --- a/src/parserutils.nim +++ b/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: diff --git a/src/types.nim b/src/types.nim index 1f6f573..9cde0c7 100644 --- a/src/types.nim +++ b/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 diff --git a/src/views/tweet.nim b/src/views/tweet.nim index 7ec7051..7805a66 100644 --- a/src/views/tweet.nim +++ b/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)