mirror of
https://github.com/jimeh/mje.git
synced 2026-02-19 09:56:41 +00:00
wip: initial commit
Extremely unfinished and work in progress.
This commit is contained in:
23
commands/midjourney.go
Normal file
23
commands/midjourney.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/jimeh/mj2n/midjourney"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewMidjourney(mc *midjourney.Client) (*cobra.Command, error) {
|
||||
cmd := &cobra.Command{
|
||||
Use: "midjourney",
|
||||
Aliases: []string{"mj"},
|
||||
Short: "MidJourney specific commands",
|
||||
}
|
||||
|
||||
recentJobsCmd, err := NewMidjourneyRecentJobs(mc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd.AddCommand(recentJobsCmd)
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
90
commands/midjourney_recent_jobs.go
Normal file
90
commands/midjourney_recent_jobs.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/jimeh/mj2n/midjourney"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewMidjourneyRecentJobs(mc *midjourney.Client) (*cobra.Command, error) {
|
||||
cmd := &cobra.Command{
|
||||
Use: "recent-jobs",
|
||||
Aliases: []string{"jobs", "recent", "rj", "j", "r"},
|
||||
Short: "List recent jobs",
|
||||
RunE: midjourneyRecentJobsRunE(mc),
|
||||
}
|
||||
|
||||
cmd.Flags().StringP("format", "f", "", "output format (yaml or json)")
|
||||
cmd.Flags().IntP("amount", "a", 50, "amount of jobs to list")
|
||||
cmd.Flags().StringP("type", "t", "", "type of jobs to list")
|
||||
cmd.Flags().StringP("order", "o", "new", "either \"new\" or \"oldest\"")
|
||||
cmd.Flags().StringP("user-id", "u", "", "user ID to list jobs for")
|
||||
cmd.Flags().StringP("page", "p", "", "page to fetch")
|
||||
cmd.Flags().Bool("dedupe", true, "dedupe results")
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func midjourneyRecentJobsRunE(mc *midjourney.Client) runEFunc {
|
||||
return func(cmd *cobra.Command, _ []string) error {
|
||||
fs := cmd.Flags()
|
||||
q := &midjourney.RecentJobsQuery{}
|
||||
|
||||
if v, err := fs.GetInt("amount"); err == nil && v > 0 {
|
||||
q.Amount = v
|
||||
}
|
||||
if v, err := fs.GetString("type"); err == nil && v != "" {
|
||||
q.JobType = midjourney.JobType(v)
|
||||
}
|
||||
if v, err := fs.GetString("order"); err == nil && v != "" {
|
||||
q.OrderBy = midjourney.Order(v)
|
||||
}
|
||||
if v, err := fs.GetString("user-id"); err == nil && v != "" {
|
||||
q.UserID = v
|
||||
}
|
||||
if v, err := fs.GetInt("page"); err == nil && v != 0 {
|
||||
q.Page = v
|
||||
}
|
||||
if v, err := fs.GetBool("dedupe"); err == nil {
|
||||
q.Dedupe = v
|
||||
}
|
||||
|
||||
rj, err := mc.RecentJobs(cmd.Context(), q)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := []*MidjourneyJob{}
|
||||
for _, j := range rj.Jobs {
|
||||
r = append(r, &MidjourneyJob{
|
||||
ID: j.ID,
|
||||
Status: string(j.CurrentStatus),
|
||||
Type: string(j.Type),
|
||||
EnqueueTime: j.EnqueueTime,
|
||||
Prompt: j.Prompt,
|
||||
ImagePaths: j.ImagePaths,
|
||||
IsPublished: j.IsPublished,
|
||||
UserID: j.UserID,
|
||||
Username: j.Username,
|
||||
FullCommand: j.FullCommand,
|
||||
ReferenceJobID: j.ReferenceJobID,
|
||||
})
|
||||
}
|
||||
format := flagString(cmd, "format")
|
||||
|
||||
return render(cmd.OutOrStdout(), format, r)
|
||||
}
|
||||
}
|
||||
|
||||
type MidjourneyJob struct {
|
||||
ID string `json:"id,omitempty" yaml:"id,omitempty"`
|
||||
Status string `json:"current_status,omitempty" yaml:"current_status,omitempty"`
|
||||
Type string `json:"type,omitempty" yaml:"type,omitempty"`
|
||||
EnqueueTime string `json:"enqueue_time,omitempty" yaml:"enqueue_time,omitempty"`
|
||||
Prompt string `json:"prompt,omitempty" yaml:"prompt,omitempty"`
|
||||
ImagePaths []string `json:"image_paths,omitempty" yaml:"image_paths,omitempty"`
|
||||
IsPublished bool `json:"is_published,omitempty" yaml:"is_published,omitempty"`
|
||||
UserID string `json:"user_id,omitempty" yaml:"user_id,omitempty"`
|
||||
Username string `json:"username,omitempty" yaml:"username,omitempty"`
|
||||
FullCommand string `json:"full_command,omitempty" yaml:"full_command,omitempty"`
|
||||
ReferenceJobID string `json:"reference_job_id,omitempty" yaml:"reference_job_id,omitempty"`
|
||||
}
|
||||
134
commands/mj2n.go
Normal file
134
commands/mj2n.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/jimeh/mj2n/midjourney"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type runEFunc func(cmd *cobra.Command, _ []string) error
|
||||
|
||||
func NewMJ2N() (*cobra.Command, error) {
|
||||
mc, err := midjourney.New(midjourney.WithUserAgent("mj2n/0.0.1-dev"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "mj2n",
|
||||
Short: "MidJourney to Notion importer",
|
||||
PersistentPreRunE: persistentPreRunE(mc),
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringP(
|
||||
"log-level", "l", "info",
|
||||
"one of: trace, debug, info, warn, error, fatal, panic",
|
||||
)
|
||||
cmd.PersistentFlags().StringP(
|
||||
"mj-token", "m", "", "MidJourney API token",
|
||||
)
|
||||
cmd.PersistentFlags().String(
|
||||
"mj-api-url", midjourney.DefaultAPIURL.String(), "MidJourney API URL",
|
||||
)
|
||||
|
||||
midjourneyCmd, err := NewMidjourney(mc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd.AddCommand(midjourneyCmd)
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func persistentPreRunE(mc *midjourney.Client) runEFunc {
|
||||
return func(cmd *cobra.Command, _ []string) error {
|
||||
err := setupZerolog(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = setupMidJourney(cmd, mc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func setupMidJourney(cmd *cobra.Command, mc *midjourney.Client) error {
|
||||
opts := []midjourney.Option{
|
||||
midjourney.WithLogger(log.Logger),
|
||||
}
|
||||
|
||||
if f := cmd.Flag("mj-token"); f.Changed {
|
||||
opts = append(opts, midjourney.WithAuthToken(f.Value.String()))
|
||||
} else if v := os.Getenv("MIDJOURNEY_TOKEN"); v != "" {
|
||||
opts = append(opts, midjourney.WithAuthToken(v))
|
||||
}
|
||||
|
||||
apiURL := flagString(cmd, "mj-api-url")
|
||||
if apiURL == "" {
|
||||
apiURL = os.Getenv("MIDJOURNEY_API_URL")
|
||||
}
|
||||
if apiURL != "" {
|
||||
opts = append(opts, midjourney.WithAPIURL(apiURL))
|
||||
}
|
||||
|
||||
return mc.Set(opts...)
|
||||
}
|
||||
|
||||
func setupZerolog(cmd *cobra.Command) error {
|
||||
var levelStr string
|
||||
if v := os.Getenv("MJ2N_DEBUG"); v != "" {
|
||||
levelStr = "debug"
|
||||
} else if v := os.Getenv("MJ2N_LOG_LEVEL"); v != "" {
|
||||
levelStr = v
|
||||
}
|
||||
|
||||
var out io.Writer = os.Stderr
|
||||
|
||||
if cmd != nil {
|
||||
out = cmd.OutOrStderr()
|
||||
fl := cmd.Flag("log-level")
|
||||
if fl != nil && (fl.Changed || levelStr == "") {
|
||||
levelStr = fl.Value.String()
|
||||
}
|
||||
}
|
||||
|
||||
if levelStr == "" {
|
||||
levelStr = "info"
|
||||
}
|
||||
|
||||
level, err := zerolog.ParseLevel(levelStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
zerolog.SetGlobalLevel(level)
|
||||
zerolog.TimeFieldFormat = ""
|
||||
|
||||
output := zerolog.ConsoleWriter{Out: out}
|
||||
output.FormatTimestamp = func(i interface{}) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
log.Logger = zerolog.New(output).With().Timestamp().Logger()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func flagString(cmd *cobra.Command, name string) string {
|
||||
var r string
|
||||
|
||||
if f := cmd.Flag(name); f != nil {
|
||||
r = f.Value.String()
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
52
commands/render.go
Normal file
52
commands/render.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func render(w io.Writer, format string, v interface{}) error {
|
||||
if format == "yaml" || format == "yml" {
|
||||
return renderYAML(w, v)
|
||||
}
|
||||
|
||||
if format == "json" {
|
||||
return renderJSON(w, v)
|
||||
}
|
||||
|
||||
if wt, ok := v.(io.WriterTo); ok {
|
||||
_, err := wt.WriteTo(w)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if tm, ok := v.(encoding.TextMarshaler); ok {
|
||||
b, err := tm.MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = w.Write(b)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return renderYAML(w, v)
|
||||
}
|
||||
|
||||
func renderYAML(w io.Writer, v interface{}) error {
|
||||
enc := yaml.NewEncoder(w)
|
||||
enc.SetIndent(2)
|
||||
|
||||
return enc.Encode(v)
|
||||
}
|
||||
|
||||
func renderJSON(w io.Writer, v interface{}) error {
|
||||
enc := json.NewEncoder(w)
|
||||
enc.SetIndent("", " ")
|
||||
|
||||
return enc.Encode(v)
|
||||
}
|
||||
Reference in New Issue
Block a user