From b03e689745366b6c073f44301964ff3ae67a5930 Mon Sep 17 00:00:00 2001 From: Ivan Velichko Date: Mon, 18 Mar 2024 23:00:25 +0000 Subject: [PATCH] wip --- cmd/content/create.go | 82 +++++++++++++++++++++++++----------------- internal/api/course.go | 60 +++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 33 deletions(-) create mode 100644 internal/api/course.go diff --git a/cmd/content/create.go b/cmd/content/create.go index bf03de7..6eb4941 100644 --- a/cmd/content/create.go +++ b/cmd/content/create.go @@ -4,8 +4,6 @@ import ( "context" "fmt" "net/url" - "os" - "path/filepath" "strings" "github.com/charmbracelet/huh" @@ -22,7 +20,7 @@ type createOptions struct { dir string - noSample bool + // noSample bool } func newCreateCommand(cli labcli.CLI) *cobra.Command { @@ -38,31 +36,18 @@ func newCreateCommand(cli labcli.CLI) *cobra.Command { } opts.name = args[1] - if opts.dir == "" { - if cwd, err := os.Getwd(); err != nil { - return labcli.WrapStatusError(fmt.Errorf("couldn't get the current working directory: %w", err)) - } else { - opts.dir = filepath.Join(cwd, opts.name) - } - } - if absDir, err := filepath.Abs(opts.dir); err != nil { - return labcli.WrapStatusError(fmt.Errorf("couldn't get the absolute path of %s: %w", opts.dir, err)) - } else { - opts.dir = absDir - } - return labcli.WrapStatusError(runCreateContent(cmd.Context(), cli, &opts)) }, } flags := cmd.Flags() - flags.BoolVar( - &opts.noSample, - "no-sample", - false, - `Don't create a sample piece of content`, - ) + // flags.BoolVar( + // &opts.noSample, + // "no-sample", + // false, + // `Don't create a sample piece of content`, + // ) flags.StringVar( &opts.dir, "dir", @@ -87,15 +72,33 @@ func runCreateContent(ctx context.Context, cli labcli.CLI, opts *createOptions) } } - cli.PrintAux("Creating a new %s in %s...\n", opts.kind, opts.dir) - - if _, err := os.Stat(opts.dir); err == nil { - return fmt.Errorf("directory %s already exists - aborting to avoid overwriting existing files", opts.dir) - } - - if err := os.MkdirAll(opts.dir, 0755); err != nil { - return fmt.Errorf("couldn't create directory %s: %w", opts.dir, err) - } + cli.PrintAux("Creating a new %s...\n", opts.kind) + + // if _, err := os.Stat(opts.dir); err == nil { + // return fmt.Errorf("directory %s already exists - aborting to avoid overwriting existing files", opts.dir) + // } + + // if cwd, err := os.Getwd(); err != nil { + // return labcli.WrapStatusError(fmt.Errorf("couldn't get the current working directory: %w", err)) + // } else { + // opts.dir = cwd + // } + // if opts.dir == "" { + // if cwd, err := os.Getwd(); err != nil { + // return labcli.WrapStatusError(fmt.Errorf("couldn't get the current working directory: %w", err)) + // } else { + // opts.dir = cwd + // } + // } + // if absDir, err := filepath.Abs(opts.dir); err != nil { + // return labcli.WrapStatusError(fmt.Errorf("couldn't get the absolute path of %s: %w", opts.dir, err)) + // } else { + // opts.dir = absDir + // } + + // if err := os.MkdirAll(opts.dir, 0755); err != nil { + // return fmt.Errorf("couldn't create directory %s: %w", opts.dir, err) + // } switch opts.kind { case KindChallenge: @@ -167,7 +170,7 @@ This is a sample challenge. You can edit this file in ... .`, return fmt.Errorf("couldn't create a sample markdown file: %w", err) } - return labcli.NewStatusError(0, "Happy authoring!") + return labcli.NewStatusError(0, "Happy authoring..") } func createTutorial(ctx context.Context, cli labcli.CLI, opts *createOptions) error { @@ -175,7 +178,20 @@ func createTutorial(ctx context.Context, cli labcli.CLI, opts *createOptions) er } func createCourse(ctx context.Context, cli labcli.CLI, opts *createOptions) error { - return nil + ch, err := cli.Client().CreateCourse(ctx, api.CreateCourseRequest{ + Name: opts.name, + Variant: api.CourseVariantModular, + }) + if err != nil { + return fmt.Errorf("couldn't create course: %w", err) + } + + cli.PrintAux("Created a new course %s\n", ch.PageURL) + if err := open.Run(ch.PageURL); err != nil { + cli.PrintAux("Couldn't open the browser. Copy the above URL into a browser manually.\n") + } + + return labcli.NewStatusError(0, "Happy authoring..") } func hasAuthorProfile(ctx context.Context, cli labcli.CLI) (bool, error) { diff --git a/internal/api/course.go b/internal/api/course.go new file mode 100644 index 0000000..e291a1b --- /dev/null +++ b/internal/api/course.go @@ -0,0 +1,60 @@ +package api + +import ( + "context" +) + +type Course struct { + CreatedAt string `json:"createdAt" yaml:"createdAt"` + UpdatedAt string `json:"updatedAt" yaml:"updatedAt"` + + Name string `json:"name" yaml:"name"` + + PageURL string `json:"pageUrl" yaml:"pageUrl"` +} + +type CourseVariant string + +const ( + CourseVariantSimple CourseVariant = "simple" + CourseVariantModular CourseVariant = "modular" +) + +type CreateCourseRequest struct { + Name string `json:"name"` + Variant CourseVariant `json:"variant"` +} + +func (c *Client) CreateCourse(ctx context.Context, req CreateCourseRequest) (*Course, error) { + body, err := toJSONBody(req) + if err != nil { + return nil, err + } + + var course Course + return &course, c.PostInto(ctx, "/courses", nil, nil, body, &course) +} + +func (c *Client) GetCourse(ctx context.Context, name string) (*Course, error) { + var course Course + return &course, c.GetInto(ctx, "/courses/"+name, nil, nil, &course) +} + +func (c *Client) ListCourses(ctx context.Context) ([]Course, error) { + var courses []Course + return courses, c.GetInto(ctx, "/courses", nil, nil, &courses) +} + +func (c *Client) ListAuthoredCourses(ctx context.Context) ([]Course, error) { + var courses []Course + return courses, c.GetInto(ctx, "/courses/authored", nil, nil, &courses) +} + +func (c *Client) DeleteCourse(ctx context.Context, name string) error { + resp, err := c.Delete(ctx, "/courses/"+name, nil, nil) + if err != nil { + return err + } + resp.Body.Close() + return nil +}