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/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 c0835ee..23e5500 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; @@ -249,6 +248,50 @@ export default class Post { // done } + /** + * Change this posts status and save it + * + * 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 + */ + + 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); + 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(); + } + /** * Schedule this post and save it * @@ -264,8 +307,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"); @@ -292,8 +335,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/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] `, 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