mixed media in tweets, allow discord embeds to select shown media, ...more
- direct image linking (buggy if you try and do /photo or /video with no index or slash) - fix activitypub images not being images - gross hack to tell discord to fetch a single image for fedi (broken for videos lol, discord's media proxy is not activitystream spec compliant)
This commit is contained in:
parent
71c772d6c9
commit
a6412968fe
@ -125,6 +125,8 @@ template fetchImpl(result, additional_headers, fetchBody) {.dirty.} =
|
|||||||
raise e
|
raise e
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
raise e
|
raise e
|
||||||
|
except ProtocolError as e:
|
||||||
|
raise e
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
echo "error: ", e.name, ", msg: ", e.msg, ", url: ", url
|
echo "error: ", e.name, ", msg: ", e.msg, ", url: ", url
|
||||||
#if "length" notin e.msg and "descriptor" notin e.msg:
|
#if "length" notin e.msg and "descriptor" notin e.msg:
|
||||||
@ -134,12 +136,11 @@ template fetchImpl(result, additional_headers, fetchBody) {.dirty.} =
|
|||||||
template retry(bod) =
|
template retry(bod) =
|
||||||
try:
|
try:
|
||||||
bod
|
bod
|
||||||
except RateLimitError:
|
except ProtocolError:
|
||||||
echo "[accounts] Rate limited, retrying ", api, " request..."
|
|
||||||
bod
|
bod
|
||||||
|
|
||||||
proc fetch*(url: Uri; api: Api; additional_headers: HttpHeaders = newHttpHeaders()): Future[JsonNode] {.async.} =
|
proc fetch*(url: Uri; api: Api; additional_headers: HttpHeaders = newHttpHeaders()): Future[JsonNode] {.async.} =
|
||||||
#retry:
|
retry:
|
||||||
var body: string
|
var body: string
|
||||||
fetchImpl(body, additional_headers):
|
fetchImpl(body, additional_headers):
|
||||||
if body.startsWith('{') or body.startsWith('['):
|
if body.startsWith('{') or body.startsWith('['):
|
||||||
@ -157,7 +158,7 @@ proc fetch*(url: Uri; api: Api; additional_headers: HttpHeaders = newHttpHeaders
|
|||||||
raise rateLimitError()
|
raise rateLimitError()
|
||||||
|
|
||||||
proc fetchRaw*(url: Uri; api: Api; additional_headers: HttpHeaders = newHttpHeaders()): Future[string] {.async.} =
|
proc fetchRaw*(url: Uri; api: Api; additional_headers: HttpHeaders = newHttpHeaders()): Future[string] {.async.} =
|
||||||
#retry:
|
retry:
|
||||||
fetchImpl(result, additional_headers):
|
fetchImpl(result, additional_headers):
|
||||||
if not (result.startsWith('{') or result.startsWith('[')):
|
if not (result.startsWith('{') or result.startsWith('[')):
|
||||||
echo resp.status, ": ", result, " --- url: ", url
|
echo resp.status, ": ", result, " --- url: ", url
|
||||||
|
|||||||
@ -33,7 +33,15 @@ proc createActivityPubRouter*(cfg: Config) =
|
|||||||
resp Http200, {"Content-Type": "application/json"}, $getMastoAPIUser(user, cfg)
|
resp Http200, {"Content-Type": "application/json"}, $getMastoAPIUser(user, cfg)
|
||||||
|
|
||||||
get "/api/v1/statuses/@id":
|
get "/api/v1/statuses/@id":
|
||||||
let id = @"id"
|
var
|
||||||
|
id = @"id"
|
||||||
|
query = ""
|
||||||
|
|
||||||
|
# stupid hack to trick discord lmao
|
||||||
|
if id.find("_") != -1:
|
||||||
|
let parts = id.split("_")
|
||||||
|
id = parts[0]
|
||||||
|
query = parts[1]
|
||||||
|
|
||||||
if id.len > 19 or id.any(c => not c.isDigit):
|
if id.len > 19 or id.any(c => not c.isDigit):
|
||||||
resp Http404, {"Content-Type": "application/json"}, """{"error":"Invalid record ID"}"""
|
resp Http404, {"Content-Type": "application/json"}, """{"error":"Invalid record ID"}"""
|
||||||
@ -54,11 +62,44 @@ proc createActivityPubRouter*(cfg: Config) =
|
|||||||
|
|
||||||
resp Http404, {"Content-Type": "application/json"}, $errJson
|
resp Http404, {"Content-Type": "application/json"}, $errJson
|
||||||
|
|
||||||
|
var
|
||||||
|
mediaType = ""
|
||||||
|
mediaIndex = ""
|
||||||
|
if query.len > 0:
|
||||||
|
let parts = query.split(":")
|
||||||
|
mediaType = parts[0]
|
||||||
|
if parts.len == 2:
|
||||||
|
mediaIndex = parts[1]
|
||||||
|
|
||||||
let
|
let
|
||||||
tweet = conv.tweet
|
tweet = conv.tweet
|
||||||
tweetUrl = &"{getUrlPrefix(cfg)}/i/status/{id}"
|
tweetUrl = &"{getUrlPrefix(cfg)}/i/status/{id}"
|
||||||
var media: seq[JsonNode] = @[]
|
var media: seq[JsonNode] = @[]
|
||||||
|
|
||||||
|
if mediaType.len > 0:
|
||||||
|
if mediaType == "video" and tweet.video.isSome or tweet.gif.isSome:
|
||||||
|
tweet.photos = @[]
|
||||||
|
elif mediaType == "photo" and tweet.photos.len > 0:
|
||||||
|
if mediaIndex.len > 0:
|
||||||
|
var index = parseInt(mediaIndex)
|
||||||
|
var useVideo = false
|
||||||
|
if index > tweet.photos.len:
|
||||||
|
if tweet.video.isSome or tweet.gif.isSome:
|
||||||
|
useVideo = true
|
||||||
|
else:
|
||||||
|
index = tweet.photos.len
|
||||||
|
elif index < 1:
|
||||||
|
index = 1
|
||||||
|
|
||||||
|
if useVideo:
|
||||||
|
tweet.photos = @[]
|
||||||
|
else:
|
||||||
|
index -= 1
|
||||||
|
tweet.video = none(Video)
|
||||||
|
let image = tweet.photos[index]
|
||||||
|
tweet.photos = @[]
|
||||||
|
tweet.photos.add(image)
|
||||||
|
|
||||||
if tweet.photos.len > 0:
|
if tweet.photos.len > 0:
|
||||||
for imageObj in tweet.photos:
|
for imageObj in tweet.photos:
|
||||||
let image = getUrlPrefix(cfg) & getPicUrl(imageObj.url)
|
let image = getUrlPrefix(cfg) & getPicUrl(imageObj.url)
|
||||||
@ -169,7 +210,25 @@ proc createActivityPubRouter*(cfg: Config) =
|
|||||||
resp Http200, {"Content-Type": "application/json"}, $postJson
|
resp Http200, {"Content-Type": "application/json"}, $postJson
|
||||||
|
|
||||||
get "/users/@name/statuses/@id":
|
get "/users/@name/statuses/@id":
|
||||||
let id = @"id"
|
var
|
||||||
|
id = @"id"
|
||||||
|
query = ""
|
||||||
|
|
||||||
|
# stupid hack to trick discord lmao
|
||||||
|
if id.find("_") != -1:
|
||||||
|
let parts = id.split("_")
|
||||||
|
id = parts[0]
|
||||||
|
query = parts[1]
|
||||||
|
|
||||||
|
var
|
||||||
|
mediaType = ""
|
||||||
|
mediaIndex = ""
|
||||||
|
if query.len > 0:
|
||||||
|
let parts = query.split(":")
|
||||||
|
mediaType = parts[0]
|
||||||
|
if parts.len == 2:
|
||||||
|
mediaIndex = parts[1]
|
||||||
|
|
||||||
if request.headers.hasKey("Accept") and request.headers["Accept"] == "application/activity+json":
|
if request.headers.hasKey("Accept") and request.headers["Accept"] == "application/activity+json":
|
||||||
if id.len > 19 or id.any(c => not c.isDigit):
|
if id.len > 19 or id.any(c => not c.isDigit):
|
||||||
resp Http404, {"Content-Type": "application/json"}, """{"error":"Invalid record ID"}"""
|
resp Http404, {"Content-Type": "application/json"}, """{"error":"Invalid record ID"}"""
|
||||||
@ -190,7 +249,33 @@ proc createActivityPubRouter*(cfg: Config) =
|
|||||||
|
|
||||||
resp Http404, {"Content-Type": "application/json"}, $errJson
|
resp Http404, {"Content-Type": "application/json"}, $errJson
|
||||||
|
|
||||||
let postJson = getActivityStream(conv.tweet, cfg, prefs)
|
let tweet = conv.tweet
|
||||||
|
|
||||||
|
if mediaType.len > 0:
|
||||||
|
if mediaType == "video" and tweet.video.isSome or tweet.gif.isSome:
|
||||||
|
tweet.photos = @[]
|
||||||
|
elif mediaType == "photo" and tweet.photos.len > 0:
|
||||||
|
if mediaIndex.len > 0:
|
||||||
|
var index = parseInt(mediaIndex)
|
||||||
|
var useVideo = false
|
||||||
|
if index > tweet.photos.len:
|
||||||
|
if tweet.video.isSome or tweet.gif.isSome:
|
||||||
|
useVideo = true
|
||||||
|
else:
|
||||||
|
index = tweet.photos.len
|
||||||
|
elif index < 1:
|
||||||
|
index = 1
|
||||||
|
|
||||||
|
if useVideo:
|
||||||
|
tweet.photos = @[]
|
||||||
|
else:
|
||||||
|
index -= 1
|
||||||
|
tweet.video = none(Video)
|
||||||
|
let image = tweet.photos[index]
|
||||||
|
tweet.photos = @[]
|
||||||
|
tweet.photos.add(image)
|
||||||
|
|
||||||
|
let postJson = getActivityStream(tweet, cfg, prefs)
|
||||||
|
|
||||||
resp Http200, {"Content-Type": "application/json"}, $postJson
|
resp Http200, {"Content-Type": "application/json"}, $postJson
|
||||||
|
|
||||||
|
|||||||
@ -37,13 +37,29 @@ proc createStatusRouter*(cfg: Config) =
|
|||||||
resp renderMain(renderUserList(await getGraphRetweeters(id, getCursor()), prefs),
|
resp renderMain(renderUserList(await getGraphRetweeters(id, getCursor()), prefs),
|
||||||
request, cfg, prefs)
|
request, cfg, prefs)
|
||||||
|
|
||||||
get "/@name/status/@id/?":
|
get "/@name/status/@id/?@m?/?@i?/?":
|
||||||
cond '.' notin @"name"
|
cond '.' notin @"name"
|
||||||
var id = @"id"
|
var
|
||||||
var rawFile = false
|
id = @"id"
|
||||||
if id.endsWith(".mp4"):
|
media = @"m"
|
||||||
rawFile = true
|
mediaIndex = @"i"
|
||||||
id.removeSuffix(".mp4")
|
|
||||||
|
let url = $request.getNativeReq().url
|
||||||
|
var
|
||||||
|
rawVideo = false
|
||||||
|
rawImage = false
|
||||||
|
if url.endsWith(".mp4") or url.endsWith(".gif"):
|
||||||
|
rawVideo = true
|
||||||
|
elif url.endsWith(".png") or url.endsWith(".jpg"):
|
||||||
|
rawImage = true
|
||||||
|
|
||||||
|
for ext in @[".mp4", ".gif", ".png", ".jpg"]:
|
||||||
|
if id.endsWith(ext):
|
||||||
|
id.removeSuffix(ext)
|
||||||
|
if media.endsWith(ext):
|
||||||
|
media.removeSuffix(ext)
|
||||||
|
if mediaIndex.endsWith(ext):
|
||||||
|
mediaIndex.removeSuffix(ext)
|
||||||
|
|
||||||
if request.headers.hasKey("Accept") and request.headers["Accept"] == "application/activity+json":
|
if request.headers.hasKey("Accept") and request.headers["Accept"] == "application/activity+json":
|
||||||
if id.len > 19 or id.any(c => not c.isDigit):
|
if id.len > 19 or id.any(c => not c.isDigit):
|
||||||
@ -65,7 +81,33 @@ proc createStatusRouter*(cfg: Config) =
|
|||||||
|
|
||||||
resp Http404, {"Content-Type": "application/json"}, $errJson
|
resp Http404, {"Content-Type": "application/json"}, $errJson
|
||||||
|
|
||||||
let postJson = getActivityStream(conv.tweet, cfg, prefs)
|
let tweet = conv.tweet
|
||||||
|
|
||||||
|
if media.len > 0:
|
||||||
|
if media == "video" and tweet.video.isSome or tweet.gif.isSome:
|
||||||
|
tweet.photos = @[]
|
||||||
|
elif media == "photo" and tweet.photos.len > 0:
|
||||||
|
if mediaIndex.len > 0:
|
||||||
|
var index = parseInt(mediaIndex)
|
||||||
|
var useVideo = false
|
||||||
|
if index > tweet.photos.len:
|
||||||
|
if tweet.video.isSome or tweet.gif.isSome:
|
||||||
|
useVideo = true
|
||||||
|
else:
|
||||||
|
index = tweet.photos.len
|
||||||
|
elif index < 1:
|
||||||
|
index = 1
|
||||||
|
|
||||||
|
if useVideo:
|
||||||
|
tweet.photos = @[]
|
||||||
|
else:
|
||||||
|
index -= 1
|
||||||
|
tweet.video = none(Video)
|
||||||
|
let image = tweet.photos[index]
|
||||||
|
tweet.photos = @[]
|
||||||
|
tweet.photos.add(image)
|
||||||
|
|
||||||
|
let postJson = getActivityStream(tweet, cfg, prefs)
|
||||||
|
|
||||||
resp Http200, {"Content-Type": "application/json"}, $postJson
|
resp Http200, {"Content-Type": "application/json"}, $postJson
|
||||||
|
|
||||||
@ -99,6 +141,36 @@ proc createStatusRouter*(cfg: Config) =
|
|||||||
avatar = tweet.user.userPic
|
avatar = tweet.user.userPic
|
||||||
time = some(tweet.time)
|
time = some(tweet.time)
|
||||||
|
|
||||||
|
let isDiscord = request.headers.getOrDefault("User-Agent").toString().contains("Discordbot")
|
||||||
|
var
|
||||||
|
realMediaIndex = mediaIndex
|
||||||
|
realUseVideo = false
|
||||||
|
if isDiscord and media.len > 0:
|
||||||
|
if media == "video" and tweet.video.isSome or tweet.gif.isSome:
|
||||||
|
tweet.photos = @[]
|
||||||
|
elif media == "photo" and tweet.photos.len > 0:
|
||||||
|
if mediaIndex.len > 0:
|
||||||
|
var index = parseInt(mediaIndex)
|
||||||
|
var useVideo = false
|
||||||
|
if index > tweet.photos.len:
|
||||||
|
if tweet.video.isSome or tweet.gif.isSome:
|
||||||
|
useVideo = true
|
||||||
|
realUseVideo = true
|
||||||
|
else:
|
||||||
|
index = tweet.photos.len
|
||||||
|
elif index < 1:
|
||||||
|
index = 1
|
||||||
|
|
||||||
|
if useVideo:
|
||||||
|
tweet.photos = @[]
|
||||||
|
else:
|
||||||
|
realMediaIndex = $index
|
||||||
|
index -= 1
|
||||||
|
tweet.video = none(Video)
|
||||||
|
let image = tweet.photos[index]
|
||||||
|
tweet.photos = @[]
|
||||||
|
tweet.photos.add(image)
|
||||||
|
|
||||||
var
|
var
|
||||||
images = tweet.photos
|
images = tweet.photos
|
||||||
video = ""
|
video = ""
|
||||||
@ -123,7 +195,7 @@ proc createStatusRouter*(cfg: Config) =
|
|||||||
|
|
||||||
if tweet.video.isSome():
|
if tweet.video.isSome():
|
||||||
let videoObj = get(tweet.video)
|
let videoObj = get(tweet.video)
|
||||||
images = @[Image(url:videoObj.thumb)]
|
images.add(Image(url:videoObj.thumb))
|
||||||
|
|
||||||
let vars = videoObj.variants.filterIt(it.contentType == mp4)
|
let vars = videoObj.variants.filterIt(it.contentType == mp4)
|
||||||
# idk why this wont sort when it sorts everywhere else
|
# idk why this wont sort when it sorts everywhere else
|
||||||
@ -131,7 +203,7 @@ proc createStatusRouter*(cfg: Config) =
|
|||||||
video = vars[^1].url
|
video = vars[^1].url
|
||||||
elif tweet.gif.isSome():
|
elif tweet.gif.isSome():
|
||||||
let gif = get(tweet.gif)
|
let gif = get(tweet.gif)
|
||||||
images = @[Image(url:gif.thumb)]
|
images.add(Image(url:gif.thumb))
|
||||||
video = getUrlPrefix(cfg) & getPicUrl(gif.url)
|
video = getUrlPrefix(cfg) & getPicUrl(gif.url)
|
||||||
#elif tweet.card.isSome():
|
#elif tweet.card.isSome():
|
||||||
# let card = tweet.card.get()
|
# let card = tweet.card.get()
|
||||||
@ -140,20 +212,44 @@ proc createStatusRouter*(cfg: Config) =
|
|||||||
# elif card.video.isSome():
|
# elif card.video.isSome():
|
||||||
# images = @[card.video.get().thumb]
|
# images = @[card.video.get().thumb]
|
||||||
|
|
||||||
if rawFile and video != "":
|
if rawVideo and video != "":
|
||||||
redirect(video)
|
redirect(video)
|
||||||
|
elif rawImage and images.len > 0:
|
||||||
|
if media == "photo" and mediaIndex.len > 0:
|
||||||
|
var index = parseInt(mediaIndex)
|
||||||
|
var useVideo = false
|
||||||
|
if index > tweet.photos.len:
|
||||||
|
if video != "":
|
||||||
|
useVideo = true
|
||||||
|
else:
|
||||||
|
index = tweet.photos.len
|
||||||
|
elif index < 1:
|
||||||
|
index = 1
|
||||||
|
|
||||||
|
if useVideo:
|
||||||
|
redirect(video)
|
||||||
|
else:
|
||||||
|
index -= 1
|
||||||
|
redirect(getPicUrl(images[index].url))
|
||||||
|
else:
|
||||||
|
redirect(getPicUrl(images[0].url))
|
||||||
|
|
||||||
|
var query = ""
|
||||||
|
if media == "video":
|
||||||
|
query = "video"
|
||||||
|
elif media == "photo" and mediaIndex.len > 0:
|
||||||
|
if realUseVideo and video != "":
|
||||||
|
query = "video"
|
||||||
|
else:
|
||||||
|
query = &"photo:{realMediaIndex}"
|
||||||
|
|
||||||
let html = renderConversation(conv, prefs, getPath() & "#m")
|
let html = renderConversation(conv, prefs, getPath() & "#m")
|
||||||
resp renderMain(html, request, cfg, prefs, title, desc, ogTitle,
|
resp renderMain(html, request, cfg, prefs, title, desc, ogTitle,
|
||||||
images=images, video=video, avatar=avatar, time=time,
|
images=images, video=video, avatar=avatar, time=time,
|
||||||
context=context, contextUrl=contextUrl, id=id)
|
context=context, contextUrl=contextUrl, id=id, media=query
|
||||||
|
)
|
||||||
|
|
||||||
get "/@name/@s/@id/@m/?@i?":
|
get "/@name/statuses/@id/?@m?/?@i?":
|
||||||
cond @"s" in ["status", "statuses"]
|
|
||||||
cond @"m" in ["video", "photo"]
|
|
||||||
redirect("/$1/status/$2" % [@"name", @"id"])
|
|
||||||
|
|
||||||
get "/@name/statuses/@id/?":
|
|
||||||
redirect("/$1/status/$2" % [@"name", @"id"])
|
redirect("/$1/status/$2" % [@"name", @"id"])
|
||||||
|
|
||||||
get "/i/web/status/@id":
|
get "/i/web/status/@id":
|
||||||
|
|||||||
@ -39,7 +39,8 @@ proc renderNavbar(cfg: Config; req: Request; rss, canonical: string): VNode =
|
|||||||
proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc="";
|
proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc="";
|
||||||
video=""; images: seq[Image] = @[]; banner=""; ogTitle="";
|
video=""; images: seq[Image] = @[]; banner=""; ogTitle="";
|
||||||
rss=""; canonical=""; avatar=""; context=""; contextUrl="";
|
rss=""; canonical=""; avatar=""; context=""; contextUrl="";
|
||||||
id=""; time: Option[DateTime] = none(DateTime)): VNode =
|
id=""; time: Option[DateTime] = none(DateTime); media=""
|
||||||
|
): VNode =
|
||||||
var theme = prefs.theme.toTheme
|
var theme = prefs.theme.toTheme
|
||||||
if "theme" in req.params:
|
if "theme" in req.params:
|
||||||
theme = req.params["theme"].toTheme
|
theme = req.params["theme"].toTheme
|
||||||
@ -166,7 +167,10 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc="";
|
|||||||
author = encodeUrl(context)
|
author = encodeUrl(context)
|
||||||
link(rel="alternate", href=(&"{getUrlPrefix(cfg)}/oembed.json?type=video&provider={encodeUrl(siteName)}&title={title}&user={author}&url={encodeUrl(contextUrl)}"), type="application/json+oembed")
|
link(rel="alternate", href=(&"{getUrlPrefix(cfg)}/oembed.json?type=video&provider={encodeUrl(siteName)}&title={title}&user={author}&url={encodeUrl(contextUrl)}"), type="application/json+oembed")
|
||||||
|
|
||||||
link(rel="alternate", href=(&"{getUrlPrefix(cfg)}/users/i/statuses/{id}"), type="application/activity+json")
|
var fediUrl = &"{getUrlPrefix(cfg)}/users/i/statuses/{id}"
|
||||||
|
if media.len > 0:
|
||||||
|
fediUrl &= "_" & media
|
||||||
|
link(rel="alternate", href=fediUrl, type="application/activity+json")
|
||||||
|
|
||||||
# this is last so images are also preloaded
|
# this is last so images are also preloaded
|
||||||
# if this is done earlier, Chrome only preloads one image for some reason
|
# if this is done earlier, Chrome only preloads one image for some reason
|
||||||
@ -176,14 +180,14 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc="";
|
|||||||
proc renderMain*(body: VNode; req: Request; cfg: Config; prefs=defaultPrefs;
|
proc renderMain*(body: VNode; req: Request; cfg: Config; prefs=defaultPrefs;
|
||||||
titleText=""; desc=""; ogTitle=""; rss=""; video="";
|
titleText=""; desc=""; ogTitle=""; rss=""; video="";
|
||||||
images: seq[Image] = @[]; banner=""; avatar=""; context="";
|
images: seq[Image] = @[]; banner=""; avatar=""; context="";
|
||||||
contextUrl=""; id=""; time: Option[DateTime] = none(DateTime)
|
contextUrl=""; id=""; time: Option[DateTime] = none(DateTime);
|
||||||
): string =
|
media=""): string =
|
||||||
|
|
||||||
let canonical = getTwitterLink(req.path, req.params)
|
let canonical = getTwitterLink(req.path, req.params)
|
||||||
|
|
||||||
let node = buildHtml(html(lang="en")):
|
let node = buildHtml(html(lang="en")):
|
||||||
renderHead(prefs, cfg, req, titleText, desc, video, images, banner, ogTitle,
|
renderHead(prefs, cfg, req, titleText, desc, video, images, banner, ogTitle,
|
||||||
rss, canonical, avatar, context, contextUrl, id, time)
|
rss, canonical, avatar, context, contextUrl, id, time, media)
|
||||||
|
|
||||||
body:
|
body:
|
||||||
renderNavbar(cfg, req, rss, canonical)
|
renderNavbar(cfg, req, rss, canonical)
|
||||||
|
|||||||
@ -64,11 +64,10 @@ proc getActivityStream*(tweet: Tweet, cfg: Config, prefs: Prefs): JsonNode =
|
|||||||
filetype = "jpeg"
|
filetype = "jpeg"
|
||||||
|
|
||||||
var mediaObj = newJObject()
|
var mediaObj = newJObject()
|
||||||
mediaObj["type"] = %"Document"
|
mediaObj["type"] = %"Image"
|
||||||
mediaObj["mediaType"] = %("image/" & filetype)
|
mediaObj["mediaType"] = %("image/" & filetype)
|
||||||
mediaObj["url"] = %image
|
mediaObj["url"] = %image
|
||||||
mediaObj["name"] = %imageObj.description
|
mediaObj["name"] = %imageObj.description
|
||||||
|
|
||||||
media.add(mediaObj)
|
media.add(mediaObj)
|
||||||
|
|
||||||
if tweet.video.isSome():
|
if tweet.video.isSome():
|
||||||
@ -79,25 +78,59 @@ proc getActivityStream*(tweet: Tweet, cfg: Config, prefs: Prefs): JsonNode =
|
|||||||
if videoObj.description.len > 0:
|
if videoObj.description.len > 0:
|
||||||
description = videoObj.description
|
description = videoObj.description
|
||||||
|
|
||||||
var mediaObj = newJObject()
|
let splitUrl = videoObj.thumb.split('.')
|
||||||
mediaObj["type"] = %"Document"
|
var filetype = splitUrl[^1]
|
||||||
mediaObj["mediaType"] = %"video/mp4"
|
if filetype == "jpg":
|
||||||
mediaObj["url"] = %vars[^1].url
|
filetype = "jpeg"
|
||||||
mediaObj["name"] = %description
|
|
||||||
|
|
||||||
media.add(mediaObj)
|
var url: seq[JsonNode] = @[]
|
||||||
|
|
||||||
|
var thumb = newJObject()
|
||||||
|
thumb["type"] = %"Link"
|
||||||
|
thumb["mediaType"] = %("image/" & filetype)
|
||||||
|
thumb["href"] = %(getUrlPrefix(cfg) & getPicUrl(videoObj.thumb))
|
||||||
|
url.add(thumb)
|
||||||
|
|
||||||
|
var mediaObj = newJObject()
|
||||||
|
mediaObj["type"] = %"Link"
|
||||||
|
mediaObj["mediaType"] = %"video/mp4"
|
||||||
|
mediaObj["href"] = %vars[^1].url
|
||||||
|
url.add(mediaObj)
|
||||||
|
|
||||||
|
var wrapper = newJObject()
|
||||||
|
wrapper["type"] = %"Video"
|
||||||
|
wrapper["name"] = %description
|
||||||
|
wrapper["url"] = %url
|
||||||
|
media.add(wrapper)
|
||||||
elif tweet.gif.isSome():
|
elif tweet.gif.isSome():
|
||||||
let
|
let
|
||||||
gif = get(tweet.gif)
|
gif = get(tweet.gif)
|
||||||
gifUrl = getUrlPrefix(cfg) & getPicUrl(gif.url)
|
gifUrl = getUrlPrefix(cfg) & getPicUrl(gif.url)
|
||||||
|
|
||||||
var mediaObj = newJObject()
|
let splitUrl = gif.thumb.split('.')
|
||||||
mediaObj["type"] = %"Document"
|
var filetype = splitUrl[^1]
|
||||||
mediaObj["mediaType"] = %"video/mp4"
|
if filetype == "jpg":
|
||||||
mediaObj["url"] = %gifUrl
|
filetype = "jpeg"
|
||||||
mediaObj["name"] = newJNull() # FIXME a11y
|
|
||||||
|
|
||||||
media.add(mediaObj)
|
var url: seq[JsonNode] = @[]
|
||||||
|
|
||||||
|
var thumb = newJObject()
|
||||||
|
thumb["type"] = %"Link"
|
||||||
|
thumb["mediaType"] = %("image/" & filetype)
|
||||||
|
thumb["href"] = %(getUrlPrefix(cfg) & getPicUrl(gif.thumb))
|
||||||
|
url.add(thumb)
|
||||||
|
|
||||||
|
var mediaObj = newJObject()
|
||||||
|
mediaObj["type"] = %"Link"
|
||||||
|
mediaObj["mediaType"] = %"video/mp4"
|
||||||
|
mediaObj["href"] = %gifUrl
|
||||||
|
url.add(mediaObj)
|
||||||
|
|
||||||
|
var wrapper = newJObject()
|
||||||
|
wrapper["type"] = %"Video"
|
||||||
|
wrapper["name"] = newJNull()
|
||||||
|
wrapper["url"] = %url
|
||||||
|
media.add(wrapper)
|
||||||
|
|
||||||
var context: seq[JsonNode] = @[]
|
var context: seq[JsonNode] = @[]
|
||||||
let contextUrl: JsonNode = %"https://www.w3.org/ns/activitystreams"
|
let contextUrl: JsonNode = %"https://www.w3.org/ns/activitystreams"
|
||||||
|
|||||||
@ -225,7 +225,8 @@ proc renderQuoteMedia(quote: Tweet; prefs: Prefs; path: string): VNode =
|
|||||||
buildHtml(tdiv(class="quote-media-container")):
|
buildHtml(tdiv(class="quote-media-container")):
|
||||||
if quote.photos.len > 0:
|
if quote.photos.len > 0:
|
||||||
renderAlbum(quote)
|
renderAlbum(quote)
|
||||||
elif quote.video.isSome:
|
|
||||||
|
if quote.video.isSome:
|
||||||
renderVideo(quote.video.get(), prefs, path)
|
renderVideo(quote.video.get(), prefs, path)
|
||||||
elif quote.gif.isSome:
|
elif quote.gif.isSome:
|
||||||
renderGif(quote.gif.get(), prefs)
|
renderGif(quote.gif.get(), prefs)
|
||||||
@ -343,7 +344,8 @@ proc renderTweet*(tweet: Tweet; prefs: Prefs; path: string; class=""; index=0;
|
|||||||
|
|
||||||
if tweet.photos.len > 0:
|
if tweet.photos.len > 0:
|
||||||
renderAlbum(tweet)
|
renderAlbum(tweet)
|
||||||
elif tweet.video.isSome:
|
|
||||||
|
if tweet.video.isSome:
|
||||||
renderVideo(tweet.video.get(), prefs, path)
|
renderVideo(tweet.video.get(), prefs, path)
|
||||||
views = tweet.video.get().views
|
views = tweet.video.get().views
|
||||||
elif tweet.gif.isSome:
|
elif tweet.gif.isSome:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user