Discourse: add categoryId and bumpedMs to Topic data (#1454)
As not all API calls return bumpedMs, make a new type to show the distinction.
This commit is contained in:
parent
e79cca6c6c
commit
23f1db6ce4
|
@ -47,6 +47,7 @@ Object {
|
|||
],
|
||||
"topic": Object {
|
||||
"authorUsername": "d11",
|
||||
"categoryId": 1,
|
||||
"id": 11,
|
||||
"timestampMs": 1564744349408,
|
||||
"title": "My First Test Post",
|
||||
|
|
|
@ -84,6 +84,8 @@ describe("plugins/discourse/createGraph", () => {
|
|||
title: "first topic",
|
||||
timestampMs: 0,
|
||||
authorUsername: "decentralion",
|
||||
categoryId: 1,
|
||||
bumpedMs: 0,
|
||||
};
|
||||
const post1 = {
|
||||
id: 1,
|
||||
|
|
|
@ -20,13 +20,29 @@ export type PostId = number;
|
|||
export type TopicId = number;
|
||||
export type CategoryId = number;
|
||||
|
||||
export type Topic = {|
|
||||
/**
|
||||
* The "view" received from the Discourse API
|
||||
* when getting a topic by ID.
|
||||
*
|
||||
* This filters some relevant data like bumpedMs,
|
||||
* and the type separation makes this distinction clear.
|
||||
*/
|
||||
export type TopicView = {|
|
||||
+id: TopicId,
|
||||
+categoryId: CategoryId,
|
||||
+title: string,
|
||||
+timestampMs: number,
|
||||
+authorUsername: string,
|
||||
|};
|
||||
|
||||
/**
|
||||
* A complete Topic object.
|
||||
*/
|
||||
export type Topic = {|
|
||||
...TopicView,
|
||||
+bumpedMs: number,
|
||||
|};
|
||||
|
||||
export type Post = {|
|
||||
+id: PostId,
|
||||
+topicId: TopicId,
|
||||
|
@ -43,7 +59,7 @@ export type Post = {|
|
|||
|};
|
||||
|
||||
export type TopicWithPosts = {|
|
||||
+topic: Topic,
|
||||
+topic: TopicView,
|
||||
// Not guaranteed to contain all the Posts in the topic—clients will need to
|
||||
// manually request some posts. The raw response actually includes a list of
|
||||
// all the PostIds in the topic, but for now we don't use them.
|
||||
|
@ -182,11 +198,12 @@ export class Fetcher implements Discourse {
|
|||
}
|
||||
failForNotOk(response);
|
||||
const json = await response.json();
|
||||
const posts = json.post_stream.posts.map(parsePost);
|
||||
const topic: Topic = {
|
||||
let posts = json.post_stream.posts.map(parsePost);
|
||||
const topic: TopicView = {
|
||||
id: json.id,
|
||||
categoryId: json.category_id,
|
||||
title: json.title,
|
||||
timestampMs: +new Date(json.created_at),
|
||||
timestampMs: Date.parse(json.created_at),
|
||||
authorUsername: json.details.created_by.username,
|
||||
};
|
||||
return {topic, posts};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
|
||||
import type {TaskReporter} from "../../util/taskReporter";
|
||||
import type {Discourse, CategoryId} from "./fetch";
|
||||
import type {Discourse, CategoryId, Topic} from "./fetch";
|
||||
import {MirrorRepository} from "./mirrorRepository";
|
||||
|
||||
export type MirrorOptions = {|
|
||||
|
@ -117,7 +117,10 @@ export class Mirror {
|
|||
const topicWithPosts = await this._fetcher.topicWithPosts(topicId);
|
||||
if (topicWithPosts != null) {
|
||||
const {topic, posts} = topicWithPosts;
|
||||
this._repo.addTopic(topic);
|
||||
// TODO: Quick hack, as TopicView does not include bumpedMs.
|
||||
// This should be resolved in the new sync logic.
|
||||
const workaroundTopic: Topic = {...topic, bumpedMs: topic.timestampMs};
|
||||
this._repo.addTopic(workaroundTopic);
|
||||
for (const post of posts) {
|
||||
addPost(post);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
type TopicId,
|
||||
type PostId,
|
||||
type Topic,
|
||||
type TopicView,
|
||||
type Post,
|
||||
type TopicWithPosts,
|
||||
type LikeAction,
|
||||
|
@ -64,7 +65,7 @@ class MockFetcher implements Discourse {
|
|||
// Only return the first post in the posts array, to ensure that we have to
|
||||
// test the functionality where we manually grab posts by ID
|
||||
const posts = [firstPost];
|
||||
return {topic: this._topic(id), posts};
|
||||
return {topic: this._topicView(id), posts};
|
||||
}
|
||||
|
||||
async likesByUser(
|
||||
|
@ -79,8 +80,16 @@ class MockFetcher implements Discourse {
|
|||
}
|
||||
|
||||
_topic(id: TopicId): Topic {
|
||||
return {
|
||||
...this._topicView(id),
|
||||
bumpedMs: 1000,
|
||||
};
|
||||
}
|
||||
|
||||
_topicView(id: TopicId): TopicView {
|
||||
return {
|
||||
id,
|
||||
categoryId: 1,
|
||||
title: `topic ${id}`,
|
||||
timestampMs: 1000,
|
||||
authorUsername: "credbot",
|
||||
|
|
|
@ -3,17 +3,11 @@
|
|||
import type {Database} from "better-sqlite3";
|
||||
import stringify from "json-stable-stringify";
|
||||
import dedent from "../../util/dedent";
|
||||
import {
|
||||
type TopicId,
|
||||
type PostId,
|
||||
type Topic,
|
||||
type Post,
|
||||
type LikeAction,
|
||||
} from "./fetch";
|
||||
import type {TopicId, PostId, Topic, Post, LikeAction} from "./fetch";
|
||||
|
||||
// The version should be bumped any time the database schema is changed,
|
||||
// so that the cache will be properly invalidated.
|
||||
const VERSION = "discourse_mirror_v4";
|
||||
const VERSION = "discourse_mirror_v5";
|
||||
|
||||
/**
|
||||
* An interface for reading the local Discourse data.
|
||||
|
@ -142,8 +136,10 @@ export class SqliteMirrorRepository
|
|||
dedent`\
|
||||
CREATE TABLE topics (
|
||||
id INTEGER PRIMARY KEY,
|
||||
category_id INTEGER NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
timestamp_ms INTEGER NOT NULL,
|
||||
bumped_ms INTEGER NOT NULL,
|
||||
author_username TEXT NOT NULL,
|
||||
FOREIGN KEY(author_username) REFERENCES users(username)
|
||||
)
|
||||
|
@ -198,17 +194,21 @@ export class SqliteMirrorRepository
|
|||
dedent`\
|
||||
SELECT
|
||||
id,
|
||||
category_id,
|
||||
title,
|
||||
timestamp_ms,
|
||||
author_username,
|
||||
title
|
||||
bumped_ms,
|
||||
author_username
|
||||
FROM topics`
|
||||
)
|
||||
.all()
|
||||
.map((x) => ({
|
||||
id: x.id,
|
||||
timestampMs: x.timestamp_ms,
|
||||
authorUsername: x.author_username,
|
||||
categoryId: x.category_id,
|
||||
title: x.title,
|
||||
timestampMs: x.timestamp_ms,
|
||||
bumpedMs: x.bumped_ms,
|
||||
authorUsername: x.author_username,
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -336,21 +336,27 @@ export class SqliteMirrorRepository
|
|||
dedent`\
|
||||
REPLACE INTO topics (
|
||||
id,
|
||||
category_id,
|
||||
title,
|
||||
timestamp_ms,
|
||||
bumped_ms,
|
||||
author_username
|
||||
) VALUES (
|
||||
:id,
|
||||
:category_id,
|
||||
:title,
|
||||
:timestamp_ms,
|
||||
:bumped_ms,
|
||||
:author_username
|
||||
)
|
||||
`
|
||||
)
|
||||
.run({
|
||||
id: topic.id,
|
||||
category_id: topic.categoryId,
|
||||
title: topic.title,
|
||||
timestamp_ms: topic.timestampMs,
|
||||
bumped_ms: topic.bumpedMs,
|
||||
author_username: topic.authorUsername,
|
||||
});
|
||||
return toAddResult(res);
|
||||
|
|
Loading…
Reference in New Issue