mirror of
https://git.sr.ht/~cadence/bibliogram
synced 2024-11-16 21:27:30 +00:00
93 lines
2.8 KiB
JavaScript
93 lines
2.8 KiB
JavaScript
const {Feed} = require("feed")
|
|
const constants = require("../constants")
|
|
const db = require("../db")
|
|
const TimelineEntry = require("./TimelineEntry")
|
|
const InstaCache = require("../cache")
|
|
const collectors = require("../collectors")
|
|
const {getFeedSetup} = require("../utils/feed")
|
|
require("../testimports")(constants, collectors, TimelineEntry, InstaCache)
|
|
|
|
/** @param {any[]} edges */
|
|
function transformEdges(edges) {
|
|
return edges.map(e => {
|
|
/** @type {import("../types").TimelineEntryAll} */
|
|
const data = e.node
|
|
const entry = collectors.getOrCreateShortcode(data.shortcode)
|
|
entry.apply(data)
|
|
return entry
|
|
})
|
|
}
|
|
|
|
class Timeline {
|
|
/**
|
|
* @param {import("./User")|import("./ReelUser")} user
|
|
* @param {string} type
|
|
*/
|
|
constructor(user, type) {
|
|
this.user = user
|
|
/** one of: "timeline", "igtv" */
|
|
this.type = type
|
|
/** @type {import("./TimelineEntry")[][]} */
|
|
this.pages = []
|
|
if (this.user.data.edge_owner_to_timeline_media) {
|
|
this.addPage(this.user.data.edge_owner_to_timeline_media)
|
|
}
|
|
}
|
|
|
|
hasNextPage() {
|
|
return !this.page_info || this.page_info.has_next_page
|
|
}
|
|
|
|
fetchNextPage() {
|
|
if (!this.hasNextPage()) return constants.symbols.NO_MORE_PAGES
|
|
const method =
|
|
this.type === "timeline" ? collectors.fetchTimelinePage
|
|
: this.type === "igtv" ? collectors.fetchIGTVPage
|
|
: null
|
|
const after = this.page_info ? this.page_info.end_cursor : ""
|
|
return method(this.user.data.id, after).then(({result: page, fromCache}) => {
|
|
const quotaUsed = fromCache ? 0 : 1
|
|
this.addPage(page)
|
|
return {page: this.pages.slice(-1)[0], quotaUsed}
|
|
})
|
|
}
|
|
|
|
async fetchUpToPage(index) {
|
|
let quotaUsed = 0
|
|
while (this.pages[index] === undefined && this.hasNextPage()) {
|
|
const result = await this.fetchNextPage()
|
|
if (typeof result !== "symbol") {
|
|
quotaUsed += result.quotaUsed
|
|
}
|
|
}
|
|
return quotaUsed
|
|
}
|
|
|
|
addPage(page) {
|
|
// update whether the user should be private
|
|
if (this.pages.length === 0 && page.count > 0) { // this is the first page, and user has posted
|
|
const shouldBePrivate = page.edges.length === 0
|
|
if (shouldBePrivate !== this.user.data.is_private) {
|
|
db.prepare("UPDATE Users SET is_private = ? WHERE user_id = ?").run(+shouldBePrivate, this.user.data.id)
|
|
this.user.data.is_private = shouldBePrivate
|
|
}
|
|
}
|
|
// add the page
|
|
this.pages.push(transformEdges(page.edges))
|
|
this.page_info = page.page_info
|
|
this.user.posts = page.count
|
|
}
|
|
|
|
async fetchFeed() {
|
|
const setup = getFeedSetup(this.user.data.username, this.user.data.biography, constants.website_origin+this.user.proxyProfilePicture, new Date(this.user.cachedAt))
|
|
const feed = new Feed(setup)
|
|
const page = this.pages[0] // only get posts from first page
|
|
await Promise.all(page.map(item =>
|
|
item.fetchFeedData().then(feedData => feed.addItem(feedData))
|
|
))
|
|
return feed
|
|
}
|
|
}
|
|
|
|
module.exports = Timeline
|