mirror of
https://github.com/spacebarchat/server.git
synced 2024-11-25 19:52:36 +01:00
test
This commit is contained in:
parent
9d6a3dc2a7
commit
a40dfcfaef
28
src/activitypub/routes/channel/#channel_id/followers.ts
Normal file
28
src/activitypub/routes/channel/#channel_id/followers.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { route } from "@spacebar/api";
|
||||||
|
import { Config, Member } from "@spacebar/util";
|
||||||
|
import { makeOrderedCollection } from "activitypub/util/OrderedCollection";
|
||||||
|
import { Router } from "express";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
export default router;
|
||||||
|
|
||||||
|
router.get("/", route({}), async (req, res) => {
|
||||||
|
// TODO auth
|
||||||
|
const { channel_id } = req.params;
|
||||||
|
|
||||||
|
const { webDomain } = Config.get().federation;
|
||||||
|
|
||||||
|
const ret = makeOrderedCollection(
|
||||||
|
req,
|
||||||
|
`https://${webDomain}/fed/channels/${channel_id}/followers`,
|
||||||
|
() =>
|
||||||
|
Member.count({
|
||||||
|
where: { guild: { channels: { id: channel_id } } },
|
||||||
|
}),
|
||||||
|
async (before, after) => {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return res.json(ret);
|
||||||
|
});
|
@ -1,6 +1,6 @@
|
|||||||
import { route } from "@spacebar/api";
|
import { route } from "@spacebar/api";
|
||||||
import { Config, Message, Snowflake } from "@spacebar/util";
|
import { Config, Message, Snowflake } from "@spacebar/util";
|
||||||
import { APOrderedCollection } from "activitypub-types";
|
import { makeOrderedCollection } from "activitypub/util/OrderedCollection";
|
||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import { FindManyOptions, FindOperator, LessThan, MoreThan } from "typeorm";
|
import { FindManyOptions, FindOperator, LessThan, MoreThan } from "typeorm";
|
||||||
|
|
||||||
@ -15,60 +15,36 @@ router.get("/", route({}), async (req, res) => {
|
|||||||
|
|
||||||
const { webDomain } = Config.get().federation;
|
const { webDomain } = Config.get().federation;
|
||||||
|
|
||||||
if (!page) {
|
const ret = makeOrderedCollection(
|
||||||
const ret: APOrderedCollection = {
|
req,
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
`https://${webDomain}/fed/channels/${channel_id}/outbox`,
|
||||||
id: `https://${webDomain}/fed/channel/${channel_id}/outbox`,
|
() => Message.count({ where: { channel_id } }),
|
||||||
type: "OrderedCollection",
|
async (before, after) => {
|
||||||
first: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true`,
|
const query: FindManyOptions<Message> & {
|
||||||
last: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true&min_id=0`,
|
where: { id?: FindOperator<string> | FindOperator<string>[] };
|
||||||
};
|
} = {
|
||||||
return res.json(ret);
|
order: { timestamp: "DESC" },
|
||||||
}
|
take: 20,
|
||||||
|
where: { channel_id: channel_id },
|
||||||
|
relations: ["author"],
|
||||||
|
};
|
||||||
|
|
||||||
const after = min_id ? `${min_id}` : undefined;
|
if (after) {
|
||||||
const before = max_id ? `${max_id}` : undefined;
|
if (BigInt(after) > BigInt(Snowflake.generate())) return [];
|
||||||
|
query.where.id = MoreThan(after);
|
||||||
|
} else if (before) {
|
||||||
|
if (BigInt(before) > BigInt(Snowflake.generate())) return [];
|
||||||
|
query.where.id = LessThan(before);
|
||||||
|
}
|
||||||
|
|
||||||
const query: FindManyOptions<Message> & {
|
const messages = await Message.find(query);
|
||||||
where: { id?: FindOperator<string> | FindOperator<string>[] };
|
|
||||||
} = {
|
|
||||||
order: { timestamp: "DESC" },
|
|
||||||
take: 20,
|
|
||||||
where: { channel_id: channel_id },
|
|
||||||
relations: ["author"],
|
|
||||||
};
|
|
||||||
|
|
||||||
if (after) {
|
return messages.map((x) => ({
|
||||||
if (BigInt(after) > BigInt(Snowflake.generate()))
|
...x,
|
||||||
return res.status(422);
|
toAP: () => x.toAnnounceAP(),
|
||||||
query.where.id = MoreThan(after);
|
}));
|
||||||
} else if (before) {
|
},
|
||||||
if (BigInt(before) > BigInt(Snowflake.generate()))
|
);
|
||||||
return res.status(422);
|
|
||||||
query.where.id = LessThan(before);
|
|
||||||
}
|
|
||||||
|
|
||||||
const messages = await Message.find(query);
|
|
||||||
|
|
||||||
// move this to like, Channel.createAPMessages or smth
|
|
||||||
const apMessages = messages.map((message) => ({
|
|
||||||
id: `https://${webDomain}/fed/channel/${message.channel_id}/messages/${message.id}`,
|
|
||||||
type: "Announce",
|
|
||||||
actor: `https://${webDomain}/fed/user/${message.author_id}`,
|
|
||||||
published: message.timestamp,
|
|
||||||
to: `https://${webDomain}/fed/channel/${message.channel_id}`,
|
|
||||||
object: message.toAP(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const ret: APOrderedCollection = {
|
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
|
||||||
id: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true`,
|
|
||||||
type: "OrderedCollection",
|
|
||||||
first: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true`,
|
|
||||||
last: `https://${webDomain}/fed/channel/${channel_id}/outbox?page=true&min_id=0`,
|
|
||||||
totalItems: await Message.count({ where: { channel_id } }),
|
|
||||||
items: apMessages,
|
|
||||||
};
|
|
||||||
|
|
||||||
return res.json(ret);
|
return res.json(ret);
|
||||||
});
|
});
|
||||||
|
41
src/activitypub/util/OrderedCollection.ts
Normal file
41
src/activitypub/util/OrderedCollection.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { APObject, APOrderedCollection } from "activitypub-types";
|
||||||
|
import { Request } from "express";
|
||||||
|
|
||||||
|
interface ActivityPubable {
|
||||||
|
toAP(): APObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const makeOrderedCollection = async <T extends ActivityPubable>(
|
||||||
|
req: Request,
|
||||||
|
id: string,
|
||||||
|
getTotalElements: () => Promise<number>,
|
||||||
|
getElements: (before?: string, after?: string) => Promise<T[]>,
|
||||||
|
): Promise<APOrderedCollection> => {
|
||||||
|
const { page, min_id, max_id } = req.query;
|
||||||
|
|
||||||
|
if (!page)
|
||||||
|
return {
|
||||||
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
id: id,
|
||||||
|
type: "OrderedCollection",
|
||||||
|
first: `${id}page=true`,
|
||||||
|
last: `${id}?page=true&min_id=0`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const after = min_id ? `${min_id}` : undefined;
|
||||||
|
const before = max_id ? `${max_id}` : undefined;
|
||||||
|
|
||||||
|
const elems = await getElements(before, after);
|
||||||
|
|
||||||
|
const items = elems.map((elem) => elem.toAP());
|
||||||
|
|
||||||
|
return {
|
||||||
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
id: `${id}?page=true`,
|
||||||
|
type: "OrderedCollection",
|
||||||
|
first: `${id}?page=true`,
|
||||||
|
last: `${id}?page=true&min_id=0`,
|
||||||
|
totalItems: await getTotalElements(),
|
||||||
|
items: items,
|
||||||
|
};
|
||||||
|
};
|
@ -16,7 +16,7 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { APNote } from "activitypub-types";
|
import type { APAnnounce, APNote } from "activitypub-types";
|
||||||
import {
|
import {
|
||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
@ -243,6 +243,19 @@ export class Message extends BaseClass {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toAnnounceAP(): APAnnounce {
|
||||||
|
const { webDomain } = Config.get().federation;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: `https://${webDomain}/fed/channel/${this.channel_id}/messages/${this.id}`,
|
||||||
|
type: "Announce",
|
||||||
|
actor: `https://${webDomain}/fed/user/${this.author_id}`,
|
||||||
|
published: this.timestamp,
|
||||||
|
to: `https://${webDomain}/fed/channel/${this.channel_id}`,
|
||||||
|
object: this.toAP(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
toAP(): APNote {
|
toAP(): APNote {
|
||||||
const { webDomain } = Config.get().federation;
|
const { webDomain } = Config.get().federation;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user