2020-02-18 00:39:20 +00:00
|
|
|
const {Feed} = require("feed")
|
2020-01-12 12:50:21 +00:00
|
|
|
const constants = require("../constants")
|
2020-01-14 14:38:33 +00:00
|
|
|
const config = require("../../../config")
|
2020-01-26 14:56:59 +00:00
|
|
|
const TimelineEntry = require("./TimelineEntry")
|
2020-01-18 15:38:14 +00:00
|
|
|
const InstaCache = require("../cache")
|
2020-01-12 12:50:21 +00:00
|
|
|
const collectors = require("../collectors")
|
2020-01-26 14:56:59 +00:00
|
|
|
require("../testimports")(constants, collectors, TimelineEntry, InstaCache)
|
2020-01-12 12:50:21 +00:00
|
|
|
|
2020-01-14 14:38:33 +00:00
|
|
|
/** @param {any[]} edges */
|
2020-01-12 12:50:21 +00:00
|
|
|
function transformEdges(edges) {
|
2020-01-26 14:56:59 +00:00
|
|
|
return edges.map(e => {
|
|
|
|
/** @type {import("../types").TimelineEntryAll} */
|
|
|
|
const data = e.node
|
|
|
|
const entry = collectors.getOrCreateShortcode(data.shortcode)
|
|
|
|
entry.apply(data)
|
|
|
|
return entry
|
|
|
|
})
|
2020-01-12 12:50:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class Timeline {
|
|
|
|
/**
|
2020-02-02 13:24:14 +00:00
|
|
|
* @param {import("./User")|import("./ReelUser")} user
|
2020-01-12 12:50:21 +00:00
|
|
|
*/
|
|
|
|
constructor(user) {
|
|
|
|
this.user = user
|
2020-01-26 14:56:59 +00:00
|
|
|
/** @type {import("./TimelineEntry")[][]} */
|
2020-01-12 12:50:21 +00:00
|
|
|
this.pages = []
|
2020-02-02 13:24:14 +00:00
|
|
|
if (this.user.data.edge_owner_to_timeline_media) {
|
|
|
|
this.addPage(this.user.data.edge_owner_to_timeline_media)
|
|
|
|
}
|
2020-01-12 12:50:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
hasNextPage() {
|
|
|
|
return this.page_info.has_next_page
|
|
|
|
}
|
|
|
|
|
|
|
|
fetchNextPage() {
|
|
|
|
if (!this.hasNextPage()) return constants.symbols.NO_MORE_PAGES
|
|
|
|
return collectors.fetchTimelinePage(this.user.data.id, this.page_info.end_cursor).then(page => {
|
|
|
|
this.addPage(page)
|
|
|
|
return this.pages.slice(-1)[0]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
async fetchUpToPage(index) {
|
|
|
|
while (this.pages[index] === undefined && this.hasNextPage()) {
|
|
|
|
await this.fetchNextPage()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
addPage(page) {
|
|
|
|
this.pages.push(transformEdges(page.edges))
|
|
|
|
this.page_info = page.page_info
|
|
|
|
}
|
2020-01-14 14:38:33 +00:00
|
|
|
|
2020-01-26 15:15:53 +00:00
|
|
|
async fetchFeed() {
|
2020-02-18 00:39:20 +00:00
|
|
|
// we likely cannot use full_name here - reel fallback would make the feed title inconsistent, leading to confusing experience
|
|
|
|
const usedName = `@${this.user.data.username}`
|
|
|
|
const feed = new Feed({
|
|
|
|
title: usedName,
|
2020-01-14 14:38:33 +00:00
|
|
|
description: this.user.data.biography,
|
2020-02-18 00:39:20 +00:00
|
|
|
id: `bibliogram:user/${this.user.data.username}`,
|
|
|
|
link: `${constants.website_origin}/u/${this.user.data.username}`,
|
|
|
|
feedLinks: {
|
|
|
|
rss: `${constants.website_origin}/u/${this.user.data.username}/rss.xml`,
|
|
|
|
atom: `${constants.website_origin}/u/${this.user.data.username}/atom.xml`
|
|
|
|
},
|
|
|
|
image: constants.website_origin+this.user.proxyProfilePicture,
|
|
|
|
updated: new Date(this.user.cachedAt),
|
|
|
|
author: {
|
|
|
|
name: usedName,
|
|
|
|
link: `${constants.website_origin}/u/${this.user.data.username}`
|
|
|
|
}
|
2020-01-14 14:38:33 +00:00
|
|
|
})
|
|
|
|
const page = this.pages[0] // only get posts from first page
|
2020-01-26 15:15:53 +00:00
|
|
|
await Promise.all(page.map(item =>
|
2020-02-18 00:39:20 +00:00
|
|
|
item.fetchFeedData().then(feedData => feed.addItem(feedData))
|
2020-01-26 15:15:53 +00:00
|
|
|
))
|
2020-01-14 14:38:33 +00:00
|
|
|
return feed
|
|
|
|
}
|
2020-01-12 12:50:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = Timeline
|