Skip to content

Instantly share code, notes, and snippets.

@jkriss
Last active June 26, 2020 06:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkriss/a2491e634efec425c6d995407b4583a7 to your computer and use it in GitHub Desktop.
Save jkriss/a2491e634efec425c6d995407b4583a7 to your computer and use it in GitHub Desktop.
function createObjects (acc, p) {
// rel="next" => 1: rel 2: next
var m = p.match(/\s*(.+)\s*=\s*"?([^"]+)"?/)
if (m) acc[m[1]] = m[2]
return acc
}
function parseLink(link) {
try {
var m = link.match(/<?([^>]*)>(.*)/)
, linkUrl = m[1]
, parts = m[2].split(';')
parts.shift()
var info = parts
.reduce(createObjects, {})
info.url = linkUrl
return info
} catch (e) {
return null
}
}
function parseLinkHeader(header) {
if (!header) return null
return header.split(/,\s*</)
.map(parseLink)
}
async function getMessage(url) {
const res = await fetch(url)
if (res.ok) {
let data
const type = res.headers.get('content-type')
const links = parseLinkHeader(res.headers.get('link'))
const permalink = links.find(link => link.rel === 'self').url
if (!links) throw new Error('No valid Link header')
if (!type) throw new Error('content-type header required')
if (type.includes('text/plain')) {
data = await res.text()
} else if (type.includes('json')) {
data = await res.json()
} else if (type.includes('image')) {
data = `<a href="${permalink}"><img src="${permalink}"></a>`
}
const date = res.headers.get('post-time')
return { body: data, contentType: type, date, t: new Date(date), links, permalink }
} else {
console.warn(res.status)
}
}
async function getMessages(streamUrl, max=20) {
const messages = []
let m
let url = streamUrl
do {
m = await getMessage(url)
if (m) {
messages.push(m)
const prev = m.links.find(link => link.rel === 'previous')
const urlStr = prev ? prev.url : null
if (streamUrl.match(/^http/)) {
url = urlStr && new URL(urlStr, streamUrl)
} else {
url = urlStr
}
}
} while (messages.length < max && m && url)
return messages
}
window.TimeStreams = {
getMessages
}
function createObjects(acc,p){var m=p.match(/\s*(.+)\s*=\s*"?([^"]+)"?/);if(m)acc[m[1]]=m[2];return acc}function parseLink(link){try{var m=link.match(/<?([^>]*)>(.*)/),linkUrl=m[1],parts=m[2].split(";");parts.shift();var info=parts.reduce(createObjects,{});info.url=linkUrl;return info}catch(e){return null}}function parseLinkHeader(header){if(!header)return null;return header.split(/,\s*</).map(parseLink)}async function getMessage(url){const res=await fetch(url);if(res.ok){let data;const type=res.headers.get("content-type");const links=parseLinkHeader(res.headers.get("link"));const permalink=links.find(link=>link.rel==="self").url;if(!links)throw new Error("No valid Link header");if(!type)throw new Error("content-type header required");if(type.includes("text/plain")){data=await res.text()}else if(type.includes("json")){data=await res.json()}else if(type.includes("image")){data=`<a href="${permalink}"><img src="${permalink}"></a>`}const date=res.headers.get("post-time");return{body:data,contentType:type,date:date,t:new Date(date),links:links,permalink:permalink}}else{console.warn(res.status)}}async function getMessages(streamUrl,max=20){const messages=[];let m;let url=streamUrl;do{m=await getMessage(url);if(m){messages.push(m);const prev=m.links.find(link=>link.rel==="previous");const urlStr=prev?prev.url:null;if(streamUrl.match(/^http/)){url=urlStr&&new URL(urlStr,streamUrl)}else{url=urlStr}}}while(messages.length<max&&m&&url);return messages}window.TimeStreams={getMessages:getMessages};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment