spieglt / FlyingCarpet

Cross-platform AirDrop. File transfer between Android, iOS, Linux, macOS, and Windows over ad hoc WiFi. No network infrastructure required, just two devices with WiFi chips in close range.
GNU General Public License v3.0
3.6k stars 145 forks source link

CLI version? #3

Open sabhiram opened 6 years ago

sabhiram commented 6 years ago

This would be quite useful for my daily workflows if I was able to get a CLI version of this working.

Imagine something like

$ flyingcarpet transfer /tmp/download.tar.gz [-password 1234 -timeout 10m]

And on the other end:

$ flyingcarpet receive /tmp/copy.tar.gz -password 1234 [-timeout 10m]

Once the transfer is done, the sender cleans up and reverts just like it already does (the rx does the same as well).

What do you think?

spieglt commented 6 years ago

It was CLI-only before I made the GUI a couple months ago, but I didn't keep the functionality unfortunately. It wouldn't be too hard to restore but would take some time. I have it on the to-do list to make a debug mode so maybe I could wrap those two tasks into one, and you're the second person to ask about it so I guess I should.

sabhiram commented 6 years ago

Maybe ill take a gander at it once I find some time. Really cool concept :) Kudos 👍

spieglt commented 6 years ago

It's actually almost done! In the cli branch. Still need to figure out how to allow for inputting list of files for multi-file transfers while also maintaining stdin for password entry. A couple other things to polish off as well but I'll have a version in the Releases page in the next few days.

sabhiram commented 6 years ago

Would be rather simple to stay bashy and allow for the input of files to be specified as a Glob expression. Golang supports globs natively using the filepath.Glob method. Usage is super simple and the input can be a single file or an expression which gives you a nice file list :)

sabhiram commented 6 years ago

additionally - we should allow the -input or whatever flag to be repeatable:

flyingcarpet transfer <glob0> <glob1> ... <globN> [options]
spieglt commented 6 years ago

filepath.Glob is a great idea, thanks. How to allow for multiple file paths properly though? The syntax will ideally be something like $ ./flyingcarpet -send pic1.jpg pic2.jpg pic3.jpg -peer linux as you suggest, but with the flags package, you'd get that whole string as the value of the flag, and then I'm not sure how to parse it safely. Unix filenames allow quotes, commas, spaces, and anything else I might use to delineate.

sabhiram commented 6 years ago

Here is what I normally do when I want custom parsing like that:

package main

import (
    "flag"
    "fmt"
    "strings"
)

type repeatedStringFlag []string

func (rs *repeatedStringFlag) String() string {
    return strings.Join([]string(*rs), ",")
}

func (rs *repeatedStringFlag) Set(v string) error {
    *rs = append(*rs, v)
    return nil
}

var repeated repeatedStringFlag

func main() {
    flag.Var(&repeated, "send", "list of files")
    flag.Parse()

    fmt.Printf("Repeated: %#v\n", repeated)
}

You can define the variable to be a custom type as long as you satisfy the interface functions String() and Set(v string) error. We simply append to our var type as needed :)

This will have usage like so:

$ ./flyingcarpet -send pic1.jpg -send pic2.jpg -send pic3.jpg -peer linux

What do you think?

spieglt commented 6 years ago

Interesting, thanks! I like that idea except that it makes the user type the -send flag multiple times, which could get annoying for longer lists.

I just had another idea while reading the docs for the flag package: I can just make it so that if someone uses the flag -send multi, then it uses flag.Args() to get a slice of the individual filenames, and leave the space-delineating negotiation to the user and shell, while also allowing for globs. So it would look like: $ ./flyingcarpet -send multi -peer linux "file name with spaces.txt" "file, with a comma.mp4" "normalFile.jpg" "expandThisGlob*"

Edit: Actually, guessing my suggestion won't work as flag.Args() would probably return ["\"file", "name", "with"...]. Can't check till later unfortunately.

sabhiram commented 6 years ago

yea that would also work quite nicely - cli users are probably able to deal w/ those subtleties anyway 👍

I also almost always alias the command to a short version of the flag as well so -s would be the same as -send.

spieglt commented 6 years ago

Actually I was able to check, and using quotes does work! So I may do that, just use -send multi and let the users tack on however many filenames and globs as they want at the end, only requiring they be in quotes. Thanks for helping me think through this.

spieglt commented 6 years ago

Okay, it's ready! Please give it a try and let me know what you think. https://github.com/spieglt/flyingcarpet/tree/cli

brian6932 commented 7 months ago

@spieglt Is there any CLI bin currently? Personally I'd rather just have a CLI only bin (maybe with a cargo feature flag).

spieglt commented 7 months ago

No, I had a note about this in the readme up until recently. You're the first person to ask about it since the Rust rewrite. It should be possible without too much trouble, but honestly I'm not sure if or when I'll get around to it unless there's more demand. At least not till after Bluetooth, internationalization, and an accessibility fix on Android.