mirror of
https://github.com/seemoo-lab/opendrop.git
synced 2026-09-16 16:16:12 -04:00
Add sending support for URLs (fixes #67)
This commit is contained in:
@@ -52,7 +52,7 @@ pip3 install ./opendrop
|
|||||||
We briefly explain how to send and receive files using `opendrop`.
|
We briefly explain how to send and receive files using `opendrop`.
|
||||||
To see all command line options, run `opendrop -h`.
|
To see all command line options, run `opendrop -h`.
|
||||||
|
|
||||||
### Sending a File
|
### Sending a File or a Link
|
||||||
|
|
||||||
Sending a file is typically a two-step procedure. You first discover devices in proximity using the `find` command.
|
Sending a file is typically a two-step procedure. You first discover devices in proximity using the `find` command.
|
||||||
Stop the process once you have found the receiver.
|
Stop the process once you have found the receiver.
|
||||||
@@ -62,7 +62,7 @@ Looking for receivers. Press Ctrl+C to stop ...
|
|||||||
Found index 0 ID eccb2f2dcfe7 name John’s iPhone
|
Found index 0 ID eccb2f2dcfe7 name John’s iPhone
|
||||||
Found index 1 ID e63138ac6ba8 name Jane’s MacBook Pro
|
Found index 1 ID e63138ac6ba8 name Jane’s MacBook Pro
|
||||||
```
|
```
|
||||||
You can then `send` a file using
|
You can then `send` a file (or link, see below) using
|
||||||
```
|
```
|
||||||
$ opendrop send -r 0 -f /path/to/some/file
|
$ opendrop send -r 0 -f /path/to/some/file
|
||||||
Asking receiver to accept ...
|
Asking receiver to accept ...
|
||||||
@@ -73,6 +73,13 @@ Uploading has been successful
|
|||||||
Instead of the `index`, you can also use `ID` or `name`.
|
Instead of the `index`, you can also use `ID` or `name`.
|
||||||
OpenDrop will try to interpret the input in the order (1) `index`, (2) `ID`, and (3) `name` and fail if no match was found.
|
OpenDrop will try to interpret the input in the order (1) `index`, (2) `ID`, and (3) `name` and fail if no match was found.
|
||||||
|
|
||||||
|
**Sending a web link.** Since v0.13, OpenDrop supports sending web links, i.e., URLs, so that receiving Apple devices will immediately open their browser upon accepting.
|
||||||
|
(Note that OpenDrop _receivers_ still only support receiving regular files.)
|
||||||
|
|
||||||
|
```
|
||||||
|
$ opendrop send -r 0 -f https://owlink.org --url
|
||||||
|
```
|
||||||
|
|
||||||
### Receiving Files
|
### Receiving Files
|
||||||
|
|
||||||
Receiving is much easier. Simply use the `receive` command. OpenDrop will accept all incoming files automatically and put received files in the current directory.
|
Receiving is much easier. Simply use the `receive` command. OpenDrop will accept all incoming files automatically and put received files in the current directory.
|
||||||
|
|||||||
+5
-3
@@ -41,6 +41,7 @@ class AirDropCli:
|
|||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("action", choices=["receive", "find", "send"])
|
parser.add_argument("action", choices=["receive", "find", "send"])
|
||||||
parser.add_argument("-f", "--file", help="File to be sent")
|
parser.add_argument("-f", "--file", help="File to be sent")
|
||||||
|
parser.add_argument("-u", "--url", help="'-f,--file is a URL", action="store_true")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-r",
|
"-r",
|
||||||
"--receiver",
|
"--receiver",
|
||||||
@@ -99,9 +100,10 @@ class AirDropCli:
|
|||||||
else: # args.action == 'send'
|
else: # args.action == 'send'
|
||||||
if args.file is None:
|
if args.file is None:
|
||||||
parser.error("Need -f,--file when using send")
|
parser.error("Need -f,--file when using send")
|
||||||
if not os.path.isfile(args.file):
|
if not os.path.isfile(args.file) and not args.url:
|
||||||
parser.error("File in -f,--file not found")
|
parser.error("File in -f,--file not found")
|
||||||
self.file = args.file
|
self.file = args.file
|
||||||
|
self.is_url = args.url
|
||||||
if args.receiver is None:
|
if args.receiver is None:
|
||||||
parser.error("Need -r,--receiver when using send")
|
parser.error("Need -r,--receiver when using send")
|
||||||
self.receiver = args.receiver
|
self.receiver = args.receiver
|
||||||
@@ -184,12 +186,12 @@ class AirDropCli:
|
|||||||
return
|
return
|
||||||
self.client = AirDropClient(self.config, (info["address"], info["port"]))
|
self.client = AirDropClient(self.config, (info["address"], info["port"]))
|
||||||
logger.info("Asking receiver to accept ...")
|
logger.info("Asking receiver to accept ...")
|
||||||
if not self.client.send_ask(self.file):
|
if not self.client.send_ask(self.file, is_url=self.is_url):
|
||||||
logger.warning("Receiver declined")
|
logger.warning("Receiver declined")
|
||||||
return
|
return
|
||||||
logger.info("Receiver accepted")
|
logger.info("Receiver accepted")
|
||||||
logger.info("Uploading file ...")
|
logger.info("Uploading file ...")
|
||||||
if not self.client.send_upload(self.file):
|
if not self.client.send_upload(self.file, is_url=self.is_url):
|
||||||
logger.warning("Uploading has failed")
|
logger.warning("Uploading has failed")
|
||||||
return
|
return
|
||||||
logger.info("Uploading has been successful")
|
logger.info("Uploading has been successful")
|
||||||
|
|||||||
+20
-16
@@ -144,7 +144,7 @@ class AirDropClient:
|
|||||||
# if name is returned, then receiver is discoverable
|
# if name is returned, then receiver is discoverable
|
||||||
return response.get("ReceiverComputerName")
|
return response.get("ReceiverComputerName")
|
||||||
|
|
||||||
def send_ask(self, file_path, icon=None):
|
def send_ask(self, file_path, is_url=False, icon=None):
|
||||||
ask_body = {
|
ask_body = {
|
||||||
"SenderComputerName": self.config.computer_name,
|
"SenderComputerName": self.config.computer_name,
|
||||||
"BundleID": "com.apple.finder",
|
"BundleID": "com.apple.finder",
|
||||||
@@ -155,18 +155,6 @@ class AirDropClient:
|
|||||||
if self.config.record_data:
|
if self.config.record_data:
|
||||||
ask_body["SenderRecordData"] = self.config.record_data
|
ask_body["SenderRecordData"] = self.config.record_data
|
||||||
|
|
||||||
if isinstance(file_path, str):
|
|
||||||
file_path = [file_path]
|
|
||||||
|
|
||||||
# generate icon for first file
|
|
||||||
with open(file_path[0], "rb") as f:
|
|
||||||
file_header = f.read(128)
|
|
||||||
flp = fleep.get(file_header)
|
|
||||||
if not icon and len(flp.mime) > 0 and "image" in flp.mime[0]:
|
|
||||||
icon = AirDropUtil.generate_file_icon(f.name)
|
|
||||||
if icon:
|
|
||||||
ask_body["FileIcon"] = icon
|
|
||||||
|
|
||||||
def file_entries(files):
|
def file_entries(files):
|
||||||
for file in files:
|
for file in files:
|
||||||
file_name = os.path.basename(file)
|
file_name = os.path.basename(file)
|
||||||
@@ -179,8 +167,20 @@ class AirDropClient:
|
|||||||
}
|
}
|
||||||
yield file_entry
|
yield file_entry
|
||||||
|
|
||||||
ask_body["Files"] = [e for e in file_entries(file_path)]
|
if isinstance(file_path, str):
|
||||||
ask_body["Items"] = []
|
file_path = [file_path]
|
||||||
|
if is_url:
|
||||||
|
ask_body["Items"] = file_path
|
||||||
|
else:
|
||||||
|
# generate icon for first file
|
||||||
|
with open(file_path[0], "rb") as f:
|
||||||
|
file_header = f.read(128)
|
||||||
|
flp = fleep.get(file_header)
|
||||||
|
if not icon and len(flp.mime) > 0 and "image" in flp.mime[0]:
|
||||||
|
icon = AirDropUtil.generate_file_icon(f.name)
|
||||||
|
ask_body["Files"] = [e for e in file_entries(file_path)]
|
||||||
|
if icon:
|
||||||
|
ask_body["FileIcon"] = icon
|
||||||
|
|
||||||
ask_binary = plistlib.dumps(
|
ask_binary = plistlib.dumps(
|
||||||
ask_body, fmt=plistlib.FMT_BINARY # pylint: disable=no-member
|
ask_body, fmt=plistlib.FMT_BINARY # pylint: disable=no-member
|
||||||
@@ -189,10 +189,14 @@ class AirDropClient:
|
|||||||
|
|
||||||
return success
|
return success
|
||||||
|
|
||||||
def send_upload(self, file_path):
|
def send_upload(self, file_path, is_url=False):
|
||||||
"""
|
"""
|
||||||
Send a file to a receiver.
|
Send a file to a receiver.
|
||||||
"""
|
"""
|
||||||
|
# Don't send an upload request if we just sent a link
|
||||||
|
if is_url:
|
||||||
|
return
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"Content-Type": "application/x-cpio",
|
"Content-Type": "application/x-cpio",
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user