Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/mappers/PlatformMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ export default class PlatformMapper extends AbstractMapper<PlatformDto> {
get: ["managePlatforms"],
set: ["managePlatforms"],
},
connected: {
type: "boolean",
label: "Connected",
get: ["managePlatforms"],
set: ["managePlatforms"],
},
// more fields from platform.settings
// added in mapper constructor
};
Expand Down Expand Up @@ -61,6 +67,9 @@ export default class PlatformMapper extends AbstractMapper<PlatformDto> {
case "active":
dto[field] = !!this.platform.active;
break;
case "connected":
dto[field] = !!this.platform.connected;
break;
case "model":
case "id":
case "user_id":
Expand Down Expand Up @@ -116,8 +125,10 @@ export default class PlatformMapper extends AbstractMapper<PlatformDto> {
if (fields.includes(field)) {
switch (field) {
case "active":
if (dto[field]) await this.user.addPlatform(this.platform.id);
else await this.user.removePlatform(this.platform.id);
this.platform.active = !!dto[field];
break;
case "connected":
this.platform.connected = !!dto[field];
break;
default: {
switch (this.mapping[field].type) {
Expand Down Expand Up @@ -154,6 +165,7 @@ export default class PlatformMapper extends AbstractMapper<PlatformDto> {
this.user.log.trace("Ignoring field: " + field);
}
}
await this.platform.save();
await this.user.data.save();
return true;
}
Expand Down
55 changes: 55 additions & 0 deletions src/models/Platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import User from "./User.ts";
export default class Platform {
id: PlatformId = PlatformId.UNKNOWN;
active: boolean = false;
connected: boolean = false;
user: User;
cache: { [id: string]: Post } = {};
defaultBody: string = "Fairpost feed";
Expand Down Expand Up @@ -75,6 +76,60 @@ export default class Platform {
return "No tests implemented for " + this.id;
}

/**
* save
*
* Save the platform - this is only 'active'
* and 'connected', as loaded in the User object
*/
async save() {
this.user.log.trace(
"Platform",
`Save ${this.id} (${this.active}, ${this.connected})`,
);
const activeIds = this.user.data
.get("settings", "FEED_PLATFORMS", "")
.split(",");
if (this.active) {
if (!activeIds.includes(this.id)) {
activeIds.push(this.id);
this.user.data.set("settings", "FEED_PLATFORMS", activeIds.join(","));
this.user.addPlatform(this);
}
} else {
const index = activeIds.indexOf(this.id);
if (index !== -1) {
activeIds.splice(index, 1);
this.user.data.set("settings", "FEED_PLATFORMS", activeIds.join(","));
this.user.removePlatform(this);
}
}
const connectedIds = this.user.data
.get("settings", "FEED_CONNECTED", "")
.split(",");
if (this.connected) {
if (!connectedIds.includes(this.id)) {
connectedIds.push(this.id);
this.user.data.set(
"settings",
"FEED_CONNECTED",
connectedIds.join(","),
);
}
} else {
const index = connectedIds.indexOf(this.id);
if (index !== -1) {
connectedIds.splice(index, 1);
this.user.data.set(
"settings",
"FEED_CONNECTED",
connectedIds.join(","),
);
}
}
await this.user.data.save();
}

/**
* refresh
*
Expand Down
120 changes: 32 additions & 88 deletions src/models/User.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { basename } from "path";
import * as readline from "node:readline/promises";

import * as platformClasses from "../platforms/index.ts";
import { PlatformId } from "../platforms/index.ts";
Expand All @@ -13,7 +12,6 @@ import UserData from "./User/UserData.ts";
import UserFiles from "./User/UserFiles.ts";
import UserLog from "./User/UserLog.ts";
import UserMapper from "../mappers/UserMapper.ts";
import { FieldMapping } from "../types/index.ts";

/**
* User - represents one fairpost user
Expand Down Expand Up @@ -215,14 +213,20 @@ export default class User {
*/
private loadPlatforms(): void {
this.log.trace("User", "loadPlatforms");
const platformIds = this.data
const activeIds = this.data
.get("settings", "FEED_PLATFORMS", "")
.split(",");
const connectedIds = this.data
.get("settings", "FEED_CONNECTED", "")
.split(",");
Object.values(platformClasses).forEach((platformClass) => {
if (typeof platformClass === "function") {
if (platformIds.includes(platformClass.id())) {
if (activeIds.includes(platformClass.id())) {
const platform = new platformClass(this);
platform.active = true;
if (connectedIds.includes(platformClass.id())) {
platform.connected = true;
}
if (this.platforms === undefined) {
this.platforms = {};
}
Expand All @@ -247,10 +251,22 @@ export default class User {
return platform;
}

const activeIds = this.data
.get("settings", "FEED_PLATFORMS", "")
.split(",");
const connectedIds = this.data
.get("settings", "FEED_CONNECTED", "")
.split(",");
Object.values(platformClasses).forEach((platformClass) => {
if (typeof platformClass === "function") {
if (platformClass.id() === platformId) {
platform = new platformClass(this);
if (activeIds.includes(platform.id)) {
platform.active = true;
}
if (connectedIds.includes(platform.id)) {
platform.connected = true;
}
}
}
});
Expand All @@ -276,96 +292,24 @@ export default class User {
}

/**
* Enable a platform on this user
* @param platformId
* @returns the enabled platform
*/
public async addPlatform(platformId: PlatformId): Promise<Platform> {
this.log.trace("User", "addPlatform", platformId);
if (
Object.values(PlatformId).includes(platformId) &&
platformId != PlatformId.UNKNOWN
) {
const platforms = this.data.get("settings", "FEED_PLATFORMS", "");
const platformIds = platforms ? platforms.split(",") : [];
if (!platformIds.includes(platformId)) {
platformIds.push(platformId);
this.data.set("settings", "FEED_PLATFORMS", platformIds.join(","));
await this.data.save();
}
this.loadPlatforms();
this.log.info(`Platform ${platformId} enabled for user ${this.id}`);
} else {
throw this.log.error("addPlatform: no such platform", platformId);
}
return this.getPlatform(platformId);
}

/**
* Disable a platform on this user
* @param platformId
* Add one platform on this users platforms[] after it has been set
* active. Does not save.
* @param platform
*/
public async removePlatform(platformId: PlatformId): Promise<void> {
this.log.trace("User", "removePlatforms", platformId);
if (
Object.values(PlatformId).includes(platformId) &&
platformId != PlatformId.UNKNOWN
) {
const platforms = this.data.get("settings", "FEED_PLATFORMS", "");
const platformIds = platforms ? platforms.split(",") : [];
const index = platformIds.indexOf(platformId);
if (index !== -1) {
platformIds.splice(index, 1);
this.data.set("settings", "FEED_PLATFORMS", platformIds.join(","));
await this.data.save();
}
this.loadPlatforms();
this.log.info(`Platform ${platformId} disabled for user ${this.id}`);
} else {
throw this.log.error("removePlatform: no such platform", platformId);
public addPlatform(platform: Platform) {
if (this.platforms && platform.active) {
this.platforms[platform.id] = platform;
}
}

/**
* @returns all data from the settings store

public getSettings(): { [key: string]: string } {
return this.data.getStore("settings");
}
* Remove one platform on this users platforms[] after it has been set
* inactive. Does not save.
* @param platform
*/

public async promptCliFields(
fields: FieldMapping,
): Promise<{ [key: string]: string }> {
const settings = {} as { [key: string]: string };
const reader = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
for (const key in fields) {
const current = this.data.get(
"settings",
key,
String(fields[key].default ?? ""),
);
const value =
(await reader.question(`${fields[key].label} ( ${current} ): `)) ||
current;
settings[key] = value;
public removePlatform(platform: Platform) {
if (this.platforms && !platform.active) {
delete this.platforms[platform.id];
}
reader.close();
return settings;
}

/**
* Update settings with values from payload
* @param payload - key/value object to save under settings store

public async putSettings(payload: { [key: string]: string }): Promise<void> {
for (const key in payload) {
this.data.set("settings", key, payload[key]);
}
await this.data.save();
}
*/
}
10 changes: 8 additions & 2 deletions src/platforms/Bluesky/Bluesky.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,20 @@ export default class Bluesky extends Platform {
async connect(operator: Operator, payload?: object) {
if (operator.ui === "cli") {
await this.auth.connectCli();
return await this.test();
const test = await this.test();
this.connected = true;
await this.save();
return test;
}
if (operator.ui === "api") {
if (!payload) {
throw this.user.log.error("Bluesky connect requires a payload");
}
await this.auth.connectApi(payload);
return await this.test();
const test = await this.test();
this.connected = true;
await this.save();
return test;
}
throw this.user.log.error(
`${this.id} connect: ui ${operator.ui} not supported`,
Expand Down
10 changes: 8 additions & 2 deletions src/platforms/LinkedIn/LinkedIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ export default class LinkedIn extends Platform {
async connect(operator: Operator, payload?: object) {
if (operator.ui === "cli") {
await this.auth.connectCli();
return await this.test();
const test = await this.test();
this.connected = true;
await this.save();
return test;
}
if (operator.ui === "api") {
if (!payload) {
Expand All @@ -74,9 +77,12 @@ export default class LinkedIn extends Platform {
const result = await this.auth.connectApi(payload);
const ready = "ready" in result && result.ready;
if (!ready) return result;
const test = await this.test();
this.connected = true;
await this.save();
return {
...result,
test: await this.test(),
test: test,
};
}

Expand Down
6 changes: 5 additions & 1 deletion src/services/Fairpost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,11 @@ class Fairpost {
"Connect payload must be an object",
);
}
const platform = await user.addPlatform(args.platform);
const platform = await user.getPlatform(args.platform);
if (!platform.active) {
platform.active = true;
await platform.save();
}
const result = await platform.connect(
operator,
args.payload as object,
Expand Down
1 change: 1 addition & 0 deletions src/types/PlatformDto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export default interface PlatformDto {
id: string;
user_id: string;
active?: boolean;
connected?: boolean;
// more fields added by platform
[key: string]: string | string[] | number | boolean | undefined;
}