Beispiel #1
0
// mainConfig is the handle for "mc config" sub-command. writes configuration data in json format to config file.
func mainConfig(ctx *cli.Context) {
	checkConfigSyntax(ctx)

	// set new custom coloring
	console.SetCustomTheme(map[string]*color.Color{
		"Alias":        color.New(color.FgCyan, color.Bold),
		"AliasMessage": color.New(color.FgGreen, color.Bold),
		"URL":          color.New(color.FgWhite),
	})

	arg := ctx.Args().First()
	tailArgs := ctx.Args().Tail()

	switch strings.TrimSpace(arg) {
	case "add":
		if strings.TrimSpace(tailArgs.First()) == "alias" {
			addAlias(tailArgs.Get(1), tailArgs.Get(2))
		}
	case "remove":
		if strings.TrimSpace(tailArgs.First()) == "alias" {
			removeAlias(tailArgs.Get(1))
		}
	case "list":
		if strings.TrimSpace(tailArgs.First()) == "alias" {
			listAliases()
		}
	}
}
Beispiel #2
0
// mainDiff - is a handler for mc diff command
func mainDiff(ctx *cli.Context) {
	checkDiffSyntax(ctx)

	console.SetCustomTheme(map[string]*color.Color{
		"DiffMessage":     color.New(color.FgGreen, color.Bold),
		"DiffOnlyInFirst": color.New(color.FgRed, color.Bold),
		"DiffType":        color.New(color.FgYellow, color.Bold),
		"DiffSize":        color.New(color.FgMagenta, color.Bold),
	})

	config := mustGetMcConfig()
	firstArg := ctx.Args().First()
	secondArg := ctx.Args().Last()

	firstURL, err := getCanonicalizedURL(firstArg, config.Aliases)
	fatalIf(err.Trace(firstArg), "Unable to parse first argument ‘"+firstArg+"’.")

	secondURL, err := getCanonicalizedURL(secondArg, config.Aliases)
	fatalIf(err.Trace(secondArg), "Unable to parse second argument ‘"+secondArg+"’.")

	newFirstURL := stripRecursiveURL(firstURL)
	for diff := range doDiffCmd(newFirstURL, secondURL, isURLRecursive(firstURL)) {
		fatalIf(diff.Error.Trace(newFirstURL, secondURL), "Failed to diff ‘"+firstURL+"’ and ‘"+secondURL+"’.")
		console.Println(diff.String())
	}
}
Beispiel #3
0
// mainCopy is bound to sub-command
func mainCopy(ctx *cli.Context) {
	checkCopySyntax(ctx)

	console.SetCustomTheme(map[string]*color.Color{
		"Copy": color.New(color.FgGreen, color.Bold),
	})

	session := newSessionV2()

	var e error
	session.Header.CommandType = "cp"
	session.Header.RootPath, e = os.Getwd()
	if e != nil {
		session.Delete()
		fatalIf(probe.NewError(e), "Unable to get current working folder.")
	}

	// extract URLs.
	var err *probe.Error
	session.Header.CommandArgs, err = args2URLs(ctx.Args())
	if err != nil {
		session.Delete()
		fatalIf(err.Trace(), "One or more unknown URL types passed.")
	}

	doCopyCmdSession(session)
	session.Delete()
}
Beispiel #4
0
// mainList - is a handler for mc ls command
func mainList(ctx *cli.Context) {
	checkListSyntax(ctx)

	args := ctx.Args()
	// Operating system tool behavior
	if globalMimicFlag && !ctx.Args().Present() {
		args = []string{"."}
	}

	console.SetCustomTheme(map[string]*color.Color{
		"File": color.New(color.FgWhite),
		"Dir":  color.New(color.FgCyan, color.Bold),
		"Size": color.New(color.FgYellow),
		"Time": color.New(color.FgGreen),
	})

	targetURLs, err := args2URLs(args)
	fatalIf(err.Trace(args...), "One or more unknown URL types passed.")

	for _, targetURL := range targetURLs {
		// if recursive strip off the "..."
		var clnt client.Client
		clnt, err = target2Client(stripRecursiveURL(targetURL))
		fatalIf(err.Trace(targetURL), "Unable to initialize target ‘"+targetURL+"’.")

		err = doList(clnt, isURLRecursive(targetURL), len(targetURLs) > 1)
		fatalIf(err.Trace(clnt.URL().String()), "Unable to list target ‘"+clnt.URL().String()+"’.")
	}
}
Beispiel #5
0
// newProgressBar - instantiate a pbBar.
func newProgressBar() barSend {
	console.SetCustomTheme(map[string]*color.Color{
		"Bar": color.New(color.FgGreen, color.Bold),
	})
	cmdCh := make(chan barMsg)
	finishCh := make(chan bool)
	go func(cmdCh <-chan barMsg, finishCh chan<- bool) {
		var started bool
		var totalBytesRead int64 // total amounts of bytes read
		bar := pb.New64(0)
		bar.SetUnits(pb.U_BYTES)
		bar.SetRefreshRate(time.Millisecond * 125)
		bar.NotPrint = true
		bar.ShowSpeed = true
		bar.Callback = func(s string) {
			console.Print(console.Colorize("Bar", "\r"+s))
		}
		switch runtime.GOOS {
		case "linux":
			bar.Format("┃▓█░┃")
			// bar.Format("█▓▒░█")
		case "darwin":
			bar.Format(" ▓ ░ ")
		default:
			bar.Format("[=> ]")
		}
		for msg := range cmdCh {
			switch msg.Op {
			case pbBarSetCaption:
				bar.Prefix(fixateBarCaption(msg.Arg.(string), getFixedWidth(bar.GetWidth(), 18)))
			case pbBarExtend:
				atomic.AddInt64(&bar.Total, msg.Arg.(int64))
			case pbBarProgress:
				if bar.Total > 0 && !started {
					started = true
					bar.Start()
				}
				if msg.Arg.(int64) > 0 {
					totalBytesRead += msg.Arg.(int64)
					bar.Add64(msg.Arg.(int64))
				}
			case pbBarPutError:
				if totalBytesRead > msg.Arg.(int64) {
					bar.Set64(totalBytesRead - msg.Arg.(int64))
				}
			case pbBarGetError:
				if msg.Arg.(int64) > 0 {
					bar.Add64(msg.Arg.(int64))
				}
			case pbBarFinish:
				if started {
					bar.Finish()
				}
				finishCh <- true
				return
			}
		}
	}(cmdCh, finishCh)
	return barSend{cmdCh, finishCh}
}
Beispiel #6
0
// mainList - is a handler for mc ls command
func mainList(ctx *cli.Context) {
	checkListSyntax(ctx)

	args := ctx.Args()
	// Operating system tool behavior
	if globalMimicFlag && !ctx.Args().Present() {
		args = []string{"."}
	}

	console.SetCustomTheme(map[string]*color.Color{
		"File": color.New(color.FgWhite),
		"Dir":  color.New(color.FgCyan, color.Bold),
		"Size": color.New(color.FgYellow),
		"Time": color.New(color.FgGreen),
	})

	config := mustGetMcConfig()
	for _, arg := range args {
		targetURL, err := getCanonicalizedURL(arg, config.Aliases)
		fatalIf(err.Trace(arg), "Unable to parse argument ‘"+arg+"’.")

		// if recursive strip off the "..."
		err = doListCmd(stripRecursiveURL(targetURL), isURLRecursive(targetURL))
		fatalIf(err.Trace(targetURL), "Unable to list target ‘"+targetURL+"’.")
	}
}
Beispiel #7
0
func mainVersion(ctx *cli.Context) {
	if ctx.Args().First() == "help" {
		cli.ShowCommandHelpAndExit(ctx, "version", 1) // last argument is exit code
	}
	console.SetCustomTheme(map[string]*color.Color{
		"Version": color.New(color.FgGreen, color.Bold),
	})
	if globalJSONFlag {
		tB, e := json.Marshal(
			struct {
				Version struct {
					Value  string `json:"value"`
					Format string `json:"format"`
				} `json:"version"`
			}{
				Version: struct {
					Value  string `json:"value"`
					Format string `json:"format"`
				}{
					Value:  mcVersion,
					Format: "RFC2616",
				},
			},
		)
		fatalIf(probe.NewError(e), "Unable to construct version string.")
		console.Println(string(tB))
		return
	}
	msg := console.Colorize("Version", fmt.Sprintf("Version: %s\n", mcVersion))
	msg += console.Colorize("Version", fmt.Sprintf("Release-Tag: %s", mcReleaseTag))
	console.Println(msg)
}
Beispiel #8
0
func mainMirror(ctx *cli.Context) {
	checkMirrorSyntax(ctx)

	console.SetCustomTheme(map[string]*color.Color{
		"Mirror": color.New(color.FgGreen, color.Bold),
	})

	var e error
	session := newSessionV2()
	session.Header.CommandType = "mirror"
	session.Header.RootPath, e = os.Getwd()
	if e != nil {
		session.Close()
		session.Delete()
		fatalIf(probe.NewError(e), "Unable to get current working folder.")
	}

	// extract URLs.
	var err *probe.Error
	session.Header.CommandArgs, err = args2URLs(ctx.Args())
	if err != nil {
		session.Close()
		session.Delete()
		fatalIf(err.Trace(ctx.Args()...), fmt.Sprintf("One or more unknown argument types found in ‘%s’.", ctx.Args()))
	}

	doMirrorCmdSession(session)
	session.Close()
	session.Delete()
}
Beispiel #9
0
func mainSession(ctx *cli.Context) {
	checkSessionSyntax(ctx)

	if !isSessionDirExists() {
		fatalIf(createSessionDir().Trace(), "Unable to create session directory.")
	}

	console.SetCustomTheme(map[string]*color.Color{
		"Command":      color.New(color.FgWhite, color.Bold),
		"SessionID":    color.New(color.FgYellow, color.Bold),
		"SessionTime":  color.New(color.FgGreen),
		"ClearSession": color.New(color.FgGreen, color.Bold),
	})

	switch strings.TrimSpace(ctx.Args().First()) {
	// list resumable sessions
	case "list":
		fatalIf(listSessions().Trace(), "Unable to list sessions.")
	case "resume":
		sid := strings.TrimSpace(ctx.Args().Tail().First())
		if !isSession(sid) {
			fatalIf(errDummy().Trace(), "Session ‘"+sid+"’ not found.")
		}

		s, err := loadSessionV2(sid)
		fatalIf(err.Trace(sid), "Unable to load session.")

		// extra check for testing purposes
		if s == nil {
			return
		}

		savedCwd, e := os.Getwd()
		fatalIf(probe.NewError(e), "Unable to verify your current working folder.")

		if s.Header.RootPath != "" {
			// chdir to RootPath
			e = os.Chdir(s.Header.RootPath)
			fatalIf(probe.NewError(e), "Unable to change directory to root path while resuming session.")
		}
		sessionExecute(s)
		err = s.Close()
		fatalIf(err.Trace(), "Unable to close session file properly.")

		err = s.Delete()
		fatalIf(err.Trace(), "Unable to clear session files properly.")

		// chdir back to saved path
		e = os.Chdir(savedCwd)
		fatalIf(probe.NewError(e), "Unable to change directory to saved path ‘"+savedCwd+"’.")

	// purge a requested pending session, if "all" purge everything
	case "clear":
		clearSession(strings.TrimSpace(ctx.Args().Tail().First()))
	}
}
Beispiel #10
0
// mainUpdate -
func mainUpdate(ctx *cli.Context) {
	checkUpdateSyntax(ctx)

	console.SetCustomTheme(map[string]*color.Color{
		"UpdateMessage": color.New(color.FgGreen, color.Bold),
	})

	arg := strings.TrimSpace(ctx.Args().First())
	switch arg {
	case "release":
		getReleaseUpdate()
	case "experimental":
		getExperimentalUpdate()
	}
}
Beispiel #11
0
// mainShare - is a handler for mc share command
func mainShare(ctx *cli.Context) {
	checkShareSyntax(ctx)

	if !isSharedURLsDataDirExists() {
		shareDir, err := getSharedURLsDataDir()
		fatalIf(err.Trace(), "Unable to get shared URL data directory")

		fatalIf(createSharedURLsDataDir().Trace(), "Unable to create shared URL data directory ‘"+shareDir+"’.")
	}
	if !isSharedURLsDataFileExists() {
		shareFile, err := getSharedURLsDataFile()
		fatalIf(err.Trace(), "Unable to get shared URL data file")

		fatalIf(createSharedURLsDataFile().Trace(), "Unable to create shared URL data file ‘"+shareFile+"’.")
	}

	console.SetCustomTheme(map[string]*color.Color{
		"Share":   color.New(color.FgGreen, color.Bold),
		"Expires": color.New(color.FgRed, color.Bold),
		"URL":     color.New(color.FgCyan, color.Bold),
	})

	args := ctx.Args()
	config := mustGetMcConfig()

	// if its only list, return quickly
	if args.Get(0) == "list" {
		err := doShareList()
		fatalIf(err.Trace(), "Unable to list shared URLs.")
		return
	}

	/// get first and last arguments
	url := args.Get(0) // url to be shared
	// default expiration is 7days
	expires := time.Duration(604800) * time.Second
	if len(args) == 2 {
		var err error
		expires, err = time.ParseDuration(args.Get(1))
		fatalIf(probe.NewError(err), "Unable to parse time argument.")
	}

	targetURL := getAliasURL(url, config.Aliases)

	// if recursive strip off the "..."
	err := doShareURL(stripRecursiveURL(targetURL), isURLRecursive(targetURL), expires)
	fatalIf(err.Trace(targetURL), "Unable to generate URL for sharing.")
}
Beispiel #12
0
// mainMakeBucket is the handler for mc mb command
func mainMakeBucket(ctx *cli.Context) {
	checkMakeBucketSyntax(ctx)

	console.SetCustomTheme(map[string]*color.Color{
		"MakeBucket": color.New(color.FgGreen, color.Bold),
	})

	config := mustGetMcConfig()
	for _, arg := range ctx.Args() {
		targetURL := getAliasURL(arg, config.Aliases)

		fatalIf(doMakeBucket(targetURL).Trace(targetURL), "Unable to make bucket ‘"+targetURL+"’.")
		Prints("%s\n", MakeBucketMessage{
			Status: "success",
			Bucket: targetURL,
		})
	}
}
Beispiel #13
0
// mainMakeBucket is the handler for mc mb command
func mainMakeBucket(ctx *cli.Context) {
	checkMakeBucketSyntax(ctx)

	console.SetCustomTheme(map[string]*color.Color{
		"MakeBucket": color.New(color.FgGreen, color.Bold),
	})

	config := mustGetMcConfig()
	for _, arg := range ctx.Args() {
		targetURL, err := getCanonicalizedURL(arg, config.Aliases)
		fatalIf(err.Trace(arg), "Unable to parse bucket ‘"+arg+"’.")

		fatalIf(doMakeBucketCmd(targetURL).Trace(targetURL), "Unable to make bucket ‘"+targetURL+"’.")
		console.Println(MakeBucketMessage{
			Status: "success",
			Bucket: targetURL,
		})
	}
}
Beispiel #14
0
func mainAccess(ctx *cli.Context) {
	checkAccessSyntax(ctx)

	console.SetCustomTheme(map[string]*color.Color{
		"Access": color.New(color.FgGreen, color.Bold),
	})

	config := mustGetMcConfig()

	switch ctx.Args().Get(0) {
	case "set":
		perms := bucketPerms(ctx.Args().Tail().Get(0))
		for _, arg := range ctx.Args().Tail().Tail() {
			targetURL := getAliasURL(arg, config.Aliases)

			fatalIf(doSetAccess(targetURL, perms).Trace(targetURL, string(perms)), "Unable to set access permission ‘"+string(perms)+"’ for ‘"+targetURL+"’.")

			Prints("%s\n", AccessMessage{
				Operation: "set",
				Status:    "success",
				Bucket:    targetURL,
				Perms:     perms,
			})
		}
	case "get":
		for _, arg := range ctx.Args().Tail() {
			targetURL := getAliasURL(arg, config.Aliases)
			perms, err := doGetAccess(targetURL)
			fatalIf(err.Trace(targetURL), "Unable to get access permission for ‘"+targetURL+"’.")

			Prints("%s\n", AccessMessage{
				Operation: "get",
				Status:    "success",
				Bucket:    targetURL,
				Perms:     perms,
			})
		}
	}
}
Beispiel #15
0
func mainAccess(ctx *cli.Context) {
	checkAccessSyntax(ctx)

	console.SetCustomTheme(map[string]*color.Color{
		"Access": color.New(color.FgGreen, color.Bold),
	})

	perms := bucketPerms(ctx.Args().First())

	config := mustGetMcConfig()
	for _, arg := range ctx.Args().Tail() {
		targetURL, err := getCanonicalizedURL(arg, config.Aliases)
		fatalIf(err.Trace(arg), "Unable to parse argument ‘"+arg+"’.")

		fatalIf(doUpdateAccessCmd(targetURL, perms).Trace(targetURL, string(perms)), "Unable to set access permission ‘"+string(perms)+"’ for ‘"+targetURL+"’.")

		console.Println(AccessMessage{
			Status: "success",
			Bucket: targetURL,
			Perms:  perms,
		})
	}
}
Beispiel #16
0
// mainDiff - is a handler for mc diff command
func mainDiff(ctx *cli.Context) {
	checkDiffSyntax(ctx)

	console.SetCustomTheme(map[string]*color.Color{
		"DiffMessage":     color.New(color.FgGreen, color.Bold),
		"DiffOnlyInFirst": color.New(color.FgRed, color.Bold),
		"DiffType":        color.New(color.FgYellow, color.Bold),
		"DiffSize":        color.New(color.FgMagenta, color.Bold),
	})

	config := mustGetMcConfig()
	firstArg := ctx.Args().First()
	secondArg := ctx.Args().Last()

	firstURL := getAliasURL(firstArg, config.Aliases)
	secondURL := getAliasURL(secondArg, config.Aliases)

	newFirstURL := stripRecursiveURL(firstURL)
	for diff := range doDiff(newFirstURL, secondURL, isURLRecursive(firstURL)) {
		fatalIf(diff.Error.Trace(newFirstURL, secondURL), "Failed to diff ‘"+firstURL+"’ and ‘"+secondURL+"’.")

		Prints("%s\n", diff)
	}
}
Beispiel #17
0
func mainConfigHost(ctx *cli.Context) {
	checkConfigHostSyntax(ctx)

	// set new custom coloring
	console.SetCustomTheme(map[string]*color.Color{
		"Host":            color.New(color.FgCyan, color.Bold),
		"API":             color.New(color.FgYellow, color.Bold),
		"HostMessage":     color.New(color.FgGreen, color.Bold),
		"AccessKeyID":     color.New(color.FgBlue, color.Bold),
		"SecretAccessKey": color.New(color.FgRed, color.Bold),
	})

	arg := ctx.Args().First()
	tailArgs := ctx.Args().Tail()

	switch strings.TrimSpace(arg) {
	case "add":
		addHost(tailArgs.Get(0), tailArgs.Get(1), tailArgs.Get(2), tailArgs.Get(3))
	case "remove":
		removeHost(tailArgs.Get(0))
	case "list":
		listHosts()
	}
}