From c02b72eea9d81d2726883d047def8485e836b56b Mon Sep 17 00:00:00 2001 From: Fairpost Date: Sun, 10 Aug 2025 18:04:18 +0200 Subject: [PATCH 1/5] feat: Add support for set-status --- README.md | 3 ++- src/models/Post.ts | 24 ++++++++++++++++++++ src/services/Fairpost.ts | 49 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 422ccdf..a0b449e 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ refresh tokens may expire, and you will have to run to get a new pair of tokens. -### Cli +### Interface ``` # basic commands: @@ -165,6 +165,7 @@ fairpost: @userid schedule-posts [--source=xxx] [--platforms=xxx,xxx|--platform= fairpost: @userid schedule-next-post --platform=xxx [--date=xxxx-xx-xx] [--sources=xxx,xxx|--stage] fairpost: @userid publish-post --post=xxx:xxx [--dry-run] fairpost: @userid publish-posts [--source=xxx] [--platforms=xxx,xxx|--platform=xxx] +fairpost: @userid set-status [--post=xxx:xxx|--posts=xxx:xxx,xxx:xxx] # feed planning: fairpost: @userid prepare-posts [--sources=xxx,xxx|--source=xxx|--stage=xxx] [--platforms=xxx,xxx|--platform=xxx] diff --git a/src/models/Post.ts b/src/models/Post.ts index c0835ee..489a309 100644 --- a/src/models/Post.ts +++ b/src/models/Post.ts @@ -249,6 +249,30 @@ export default class Post { // done } + /** + * Change this posts status and save it + * + * this just sets the status to whatever given + * @param status - the status to change it to + */ + + async setStatus(status: PostStatus) { + this.platform.user.log.trace("Post", "setStatus", status); + if (!this.prepared) { + throw this.platform.user.log.error("Post is not prepared"); + } + if (!this.valid) { + throw this.platform.user.log.error("Post is not valid"); + } + + if (this.status === status) { + throw this.platform.user.log.error("Post already on status " + status); + } + this.platform.user.log.warn("Changing post status to " + status); + this.status = status; + await this.save(); + } + /** * Schedule this post and save it * diff --git a/src/services/Fairpost.ts b/src/services/Fairpost.ts index b0a5358..50477f9 100644 --- a/src/services/Fairpost.ts +++ b/src/services/Fairpost.ts @@ -550,6 +550,54 @@ class Fairpost { } break; } + case "set-status": { + if (!permissions.schedulePosts) { + throw new Error("Missing permissions for command " + command); + } + if (!user) { + throw new Error("user is required for command " + command); + } + if (!args.platforms && args.platform) { + args.platforms = [args.platform]; + } + if (!args.sources && args.source) { + args.sources = [args.source]; + } + if (!args.sources) { + throw user.log.error( + "CommandHandler " + command, + "Missing argument: sources", + ); + } + if (!args.status) { + throw user.log.error( + "CommandHandler " + command, + "Missing argument: status", + ); + } + const feed = user.getFeed(); + const sources = await feed.getSources(args.sources); + const platforms = user.getPlatforms(args.platforms); + output = {} as { [id in PlatformId]: CombinedResult }; + for (const source of sources) { + for (const platform of platforms) { + try { + const post = await platform.getPost(source); + await post.setStatus(args.status); + output[platform.id] = { + success: true, + result: await post.mapper.getDto(operator), + }; + } catch (e) { + output[platform.id] = { + success: false, + message: e instanceof Error ? e.message : JSON.stringify(e), + }; + } + } + } + break; + } case "schedule-post": { if (!permissions.schedulePosts) { throw new Error("Missing permissions for command " + command); @@ -864,6 +912,7 @@ class Fairpost { `${cmd} @userid schedule-next-post --platform=xxx [--date=xxxx-xx-xx] [--sources=xxx,xxx|--stage=xxx]`, `${cmd} @userid publish-post --post=xxx:xxx [--dry-run]`, `${cmd} @userid publish-posts [--source=xxx] [--platforms=xxx,xxx|--platform=xxx]`, + `${cmd} @userid set-status [--post=xxx:xxx|--posts=xxx:xxx,xxx:xxx]`, "\n# feed planning:", `${cmd} @userid prepare-posts [--sources=xxx,xxx|--source=xxx|--stage=xxx] [--platforms=xxx,xxx|--platform=xxx]`, `${cmd} @userid schedule-next-posts [--date=xxxx-xx-xx] [--sources=xxx,xxx|--stage] [--platforms=xxx,xxx] `, From 24b5322fd487a4e7a15076a4b000208c0f4cee22 Mon Sep 17 00:00:00 2001 From: Fairpost Date: Sun, 10 Aug 2025 18:10:55 +0200 Subject: [PATCH 2/5] feat: Remove post.skip in favor of PostStatus.CANCELED --- src/mappers/PostMapper.ts | 12 ------------ src/models/Platform.ts | 19 ++----------------- src/models/Post.ts | 9 ++++----- src/models/Source.ts | 1 - src/types/PostDto.ts | 1 - 5 files changed, 6 insertions(+), 36 deletions(-) diff --git a/src/mappers/PostMapper.ts b/src/mappers/PostMapper.ts index cbd5788..f838d9f 100644 --- a/src/mappers/PostMapper.ts +++ b/src/mappers/PostMapper.ts @@ -42,12 +42,6 @@ export default class PostMapper extends AbstractMapper { get: ["managePosts"], set: ["none"], }, - skip: { - type: "boolean", - label: "Skip", - get: ["managePosts"], - set: ["managePosts"], - }, status: { type: "string", label: "Status", @@ -156,9 +150,6 @@ export default class PostMapper extends AbstractMapper { case "valid": dto[field] = this.post.valid; break; - case "skip": - dto[field] = this.post.skip; - break; case "status": dto[field] = this.post.status; break; @@ -214,9 +205,6 @@ export default class PostMapper extends AbstractMapper { for (const field in dto) { if (field in fields) { switch (field) { - case "skip": - this.post.skip = !!dto[field]; - break; case "scheduled": this.post.scheduled = new Date((dto.scheduled as string) ?? ""); break; diff --git a/src/models/Platform.ts b/src/models/Platform.ts index 243de35..c67ca9d 100644 --- a/src/models/Platform.ts +++ b/src/models/Platform.ts @@ -228,7 +228,6 @@ export default class Platform { * This also does some janitor checks .. * - if a post is scheduled without a date, it will be unscheduled * - if a post is already published, it will be marked as such - * - if a post is marked as skip, it will be unscheduled * @param sources * @returns the above post or none */ @@ -251,15 +250,6 @@ export default class Platform { await post.save(); continue; } - if (post.skip) { - this.user.log.warn( - "Found scheduled post marked skip. Unscheduling post.", - post.id, - ); - post.status = PostStatus.UNSCHEDULED; - await post.save(); - continue; - } if (post.published) { this.user.log.warn( "Found scheduled post previously published. Marking published.", @@ -310,7 +300,7 @@ export default class Platform { * * Presume the post may have already been prepared * before, and manually adapted later. For example, - * post.skip may have manually been set to true. + * post.status may have manually been set to canceled. * @param source - the source for which to prepare a post for this platform * @param save - wether to save the post already * @returns the prepared post @@ -404,12 +394,7 @@ export default class Platform { const nextDate = date ? date : await this.getNextPostDate(includeAll); for (const source of sources) { const post = await this.getPost(source); - if ( - post && - post.valid && - !post.skip && - post.status === PostStatus.UNSCHEDULED - ) { + if (post && post.valid && post.status === PostStatus.UNSCHEDULED) { await post.schedule(nextDate); return post; } diff --git a/src/models/Post.ts b/src/models/Post.ts index 489a309..e55e16a 100644 --- a/src/models/Post.ts +++ b/src/models/Post.ts @@ -24,7 +24,6 @@ export default class Post { source: Source; platform: Platform; valid: boolean = false; - skip: boolean = false; status: PostStatus = PostStatus.UNKNOWN; prepared: boolean = true; private originalStatus: PostStatus = PostStatus.UNKNOWN; @@ -288,8 +287,8 @@ export default class Post { if (!this.valid) { throw this.platform.user.log.error("Post is not valid"); } - if (this.skip) { - throw this.platform.user.log.error("Post is marked to be skipped"); + if (this.status === PostStatus.CANCELED) { + throw this.platform.user.log.error("Post has status canceled"); } if (this.status !== PostStatus.UNSCHEDULED) { this.platform.user.log.warn("Rescheduling post"); @@ -316,8 +315,8 @@ export default class Post { if (!this.valid) { throw this.platform.user.log.error("Post is not valid", this.id); } - if (this.skip) { - throw this.platform.user.log.error("Post is marked skip", this.id); + if (this.status === PostStatus.CANCELED) { + throw this.platform.user.log.error("Post has status canceled", this.id); } if (this.published) { throw this.platform.user.log.error("Post was already published", this.id); diff --git a/src/models/Source.ts b/src/models/Source.ts index fc59899..dc77b32 100644 --- a/src/models/Source.ts +++ b/src/models/Source.ts @@ -142,7 +142,6 @@ export default class Source { (post: Post) => post.status === PostStatus.PUBLISHED || post.status === PostStatus.CANCELED || - post.skip || !post.valid, ) ) { diff --git a/src/types/PostDto.ts b/src/types/PostDto.ts index ceb2df7..d9f7fc5 100644 --- a/src/types/PostDto.ts +++ b/src/types/PostDto.ts @@ -6,7 +6,6 @@ export default interface PostDto { platform_id?: string; source_id?: string; valid?: boolean; - skip?: boolean; status?: PostStatus; scheduled?: string; // date published?: string; // date From ee05b85f611e5abe4a3c1f245d781e9225e9939d Mon Sep 17 00:00:00 2001 From: Fairpost Date: Sun, 10 Aug 2025 18:27:01 +0200 Subject: [PATCH 3/5] feat: Homor published and scheduled dates when changing status --- src/models/Post.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/models/Post.ts b/src/models/Post.ts index e55e16a..6743ff4 100644 --- a/src/models/Post.ts +++ b/src/models/Post.ts @@ -268,6 +268,25 @@ export default class Post { throw this.platform.user.log.error("Post already on status " + status); } this.platform.user.log.warn("Changing post status to " + status); + switch (status) { + case PostStatus.UNSCHEDULED: + this.platform.user.log.warn("Removing scheduled and published dates"); + delete this.scheduled; + delete this.published; + break; + case PostStatus.SCHEDULED: + this.platform.user.log.warn( + "Resetting scheduled date, removing published date, r", + ); + this.scheduled = this.scheduled || new Date(); + delete this.published; + break; + case PostStatus.PUBLISHED: + this.platform.user.log.warn("Resetting scheduled and published dates"); + this.scheduled = this.scheduled || new Date(); + this.published = this.published || new Date(); + break; + } this.status = status; await this.save(); } From 289857c489c1dd1b1fcc551bcbc07ada5b2f659c Mon Sep 17 00:00:00 2001 From: Fairpost Date: Sun, 10 Aug 2025 18:30:10 +0200 Subject: [PATCH 4/5] doc: Update docblock --- src/models/Post.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/models/Post.ts b/src/models/Post.ts index 6743ff4..1131dee 100644 --- a/src/models/Post.ts +++ b/src/models/Post.ts @@ -251,7 +251,9 @@ export default class Post { /** * Change this posts status and save it * - * this just sets the status to whatever given + * this just sets the status to whatever given; also updates + * or removes published and scheduled dates to match + * * @param status - the status to change it to */ From ac10c33be791dd0dd2210a3a36085ef9d5f468d0 Mon Sep 17 00:00:00 2001 From: Fairpost Date: Sun, 10 Aug 2025 18:31:40 +0200 Subject: [PATCH 5/5] chore: Lint:fix --- src/models/Post.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/models/Post.ts b/src/models/Post.ts index 1131dee..23e5500 100644 --- a/src/models/Post.ts +++ b/src/models/Post.ts @@ -253,7 +253,6 @@ export default class Post { * * this just sets the status to whatever given; also updates * or removes published and scheduled dates to match - * * @param status - the status to change it to */