diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index bf479b3..9d706b6 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -1,3 +1,14 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# GitHub recommends pinning actions to a commit SHA. +# To get a newer version, you will need to update the SHA. +# You can also reference a tag or branch, but the action may change without warning. + +# Build a Docker image whenever it is pushed to master + name: Docker Image CI on: @@ -13,6 +24,6 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Build the Docker image run: docker build --pull . -f Dockerfile -t pairdrop diff --git a/.github/workflows/github-image.yml b/.github/workflows/github-image.yml index fb6d30d..05dcffc 100644 --- a/.github/workflows/github-image.yml +++ b/.github/workflows/github-image.yml @@ -7,6 +7,8 @@ # To get a newer version, you will need to update the SHA. # You can also reference a tag or branch, but the action may change without warning. +# Create a Docker image and push it to ghcr.io whenever a new version tag is pushed + name: GHCR Image CI on: @@ -27,16 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Setup qemu - uses: docker/setup-qemu-action@v2.1.0 + uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - name: Setup Docker Buildx - uses: docker/setup-buildx-action@v2.5.0 + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 - name: Log in to the Container registry - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -44,12 +46,12 @@ jobs: - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + uses: docker/metadata-action@31cebacef4805868f9ce9a0cb03ee36c32df2ac4 # v5.3.0 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - name: Build and push Docker image - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 with: context: . platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/zip-release.yml b/.github/workflows/zip-release.yml new file mode 100644 index 0000000..115b08c --- /dev/null +++ b/.github/workflows/zip-release.yml @@ -0,0 +1,35 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# GitHub recommends pinning actions to a commit SHA. +# To get a newer version, you will need to update the SHA. +# You can also reference a tag or branch, but the action may change without warning. + +# Create a new zip file from pairdrop-cli whenever a new version tag is pushed + +name: Zip Release + +on: + push: + tags: + - "v*.*.*" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Archive Release + uses: thedoctor0/zip-release@b57d897cb5d60cb78b51a507f63fa184cfe35554 # v0.7.6 + with: + type: 'zip' + filename: 'pairdrop-cli.zip' + path: 'pairdrop-cli' + exclusions: '*.git* /*node_modules/* .editorconfig' + - name: Upload Release + uses: ncipollo/release-action@6c75be85e571768fa31b40abf38de58ba0397db5 # v1.13.0 + with: + artifacts: "pairdrop-cli.zip" + token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index b339a2b..891dc88 100644 --- a/README.md +++ b/README.md @@ -67,10 +67,11 @@ Developed based on [Snapdrop](https://github.com/RobinLinus/snapdrop) * Multiple files are transferred at once with an overall progress indicator ### Send Files or Text Directly From Share Menu, Context Menu or CLI -* [Send files directly from context menu on Windows](/docs/how-to.md#send-files-directly-from-context-menu-on-windows) -* [Send directly from share menu on iOS](/docs/how-to.md#send-directly-from-share-menu-on-ios) -* [Send directly from share menu on Android](/docs/how-to.md#send-directly-from-share-menu-on-android) -* [Send directly via command-line interface](/docs/how-to.md#send-directly-via-command-line-interface) +* [Send files directly from context menu on Windows](/docs/how-to.md#send-multiple-files-and-directories-directly-from-context-menu-on-windows) +* [Send files directly from context menu on Ubuntu (using Nautilus)](/docs/how-to.md#send-multiple-files-and-directories-directly-from-context-menu-on-ubuntu-using-nautilus) +* [Send files directly from share menu on iOS](/docs/how-to.md#send-directly-from-share-menu-on-ios) +* [Send files directly from share menu on Android](/docs/how-to.md#send-directly-from-share-menu-on-android) +* [Send files directly via command-line interface](/docs/how-to.md#send-directly-via-command-line-interface) ### Other changes * Change your display name permanently to easily differentiate your devices @@ -99,9 +100,11 @@ Developed based on [Snapdrop](https://github.com/RobinLinus/snapdrop) * [NodeJS](https://nodejs.org/en/) backend * [Progressive Web App](https://wikipedia.org/wiki/Progressive_Web_App) * [IndexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) -* [zip.js](https://gildas-lormeau.github.io/zip.js/) -* [cyrb53](https://github.com/bryc) super fast hash function * [Weblate](https://weblate.org/) Web based localization tool +* [zip.js](https://github.com/gildas-lormeau/zip.js) JavaScript library to zip and unzip files ([BSD 3-Clause License](licenses/BSD_3-Clause-zip-js)) +* [NoSleep](https://github.com/richtr/NoSleep.js) JavaScript library to prevent display sleep and enable wake lock in any Android or iOS web browser ([MIT License](licenses/MIT-NoSleep)) +* [heic2any](https://github.com/alexcorvi/heic2any) JavaScript library to convert HEIC/HEIF images to PNG/GIF/JPEG ([MIT License](licenses/MIT-heic2any)) +* [cyrb53](https://github.com/bryc) Super fast hash function Have any questions? Read our [FAQ](/docs/faq.md). diff --git a/docs/how-to.md b/docs/how-to.md index f38d5f2..7db17fc 100644 --- a/docs/how-to.md +++ b/docs/how-to.md @@ -1,84 +1,120 @@ # How-To -## Send files directly from context menu on Windows -### Registering to open files with PairDrop -The [File Handling API](https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/handle-files) is implemented - -This is still experimental and must be enabled via a flag **before** the PWA is installed to Windows. -1. [Enabled feature in Edge](https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/handle-files#enable-the-file-handling-api) -2. Install PairDrop by visiting https://pairdrop.net/ with the Edge web browser and install it as described [here](faq.md#help--i-cant-install-the-pwa-). -3. You are done! You can now send most files one at a time via PairDrop: - - _context menu > Open with > PairDrop_ - -[//]: # (Todo: add screenshots) - -### Sending multiple files to PairDrop -Outstandingly, it is also possible to send multiple files to PairDrop \ -via the context menu by adding PairDrop to the `Send to` menu: -1. [Register PairDrop as file handler](#registering-to-open-files-with-pairdrop) -2. Hit Windows Key+R, type: `shell:programs` and hit Enter. -3. Copy the PairDrop shortcut from the directory -4. Hit Windows Key+R, type: `shell:sendto` and hit Enter. -5. Paste the copied shortcut into the directory -6. You are done! You can now send multiple files (but no directories) directly via PairDrop: - - _context menu > Send to > PairDrop_ - -[//]: # (Todo: add screenshots) ## Send directly from share menu on iOS I created an iOS shortcut to send images, files, folder, URLs \ or text directly from the share-menu https://routinehub.co/shortcut/13990/ -[//]: # (Todo: add doku with screenshots) +[//]: # (Todo: Add screenshots) +
## Send directly from share menu on Android The [Web Share Target API](https://developer.mozilla.org/en-US/docs/Web/Manifest/share_target) is implemented. When the PWA is installed, it will register itself to the share-menu of the device automatically. +
## Send directly via command-line interface -Send files or text with PairDrop via command-line interface. - +Send files or text with PairDrop via command-line interface. \ This opens PairDrop in the default browser where you can choose the receiver. ### Usage ```bash -$ pairdrop -h -Current domain: https://pairdrop.net/ +pairdrop -h +``` +```bash +Send files or text with PairDrop via command-line interface. +Current domain: https://pairdrop-dev.onrender.com/ Usage: -Open PairDrop: pairdrop -Send files: pairdrop file/directory -Send text: pairdrop -t "text" -Specify domain: pairdrop -d "https://pairdrop.net/" -Show this help text: pairdrop (-h|--help) +Open PairDrop: pairdrop +Send files: pairdrop file1/directory1 (file2/directory2 file3/directory3 ...) +Send text: pairdrop -t "text" +Specify domain: pairdrop -d "https://pairdrop.net/" +Show this help text: pairdrop (-h|--help) + +This pairdrop-cli version was released alongside v1.10.0 ``` -On Windows Command Prompt you need to use bash: `bash pairdrop -h` - +
### Setup Download the bash file: [pairdrop-cli/pairdrop](/pairdrop-cli/pairdrop). #### Linux -1. Put the file in a preferred folder e.g. `/usr/local/bin` -2. Make sure the bash file is executable. Otherwise, use `chmod +x pairdrop` -3. Add absolute path of the folder to PATH variable to make `pairdrop` available globally by executing - `export PATH=$PATH:/opt/pairdrop-cli` +1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases) +2. Unzip the archive to a folder of your choice e.g. `/usr/local/bin/pairdrop-cli/` +3. Make sure the bash file `/usr/local/bin/pairdrop-cli/pairdrop` is executable. Otherwise, use `chmod +x pairdrop` +4. Add absolute path of the folder to PATH variable to make `pairdrop` available globally by executing + `export PATH=$PATH:/usr/local/bin/pairdrop-cli/` + +
#### Mac 1. add bash file to `/usr/local/bin` +
+ #### Windows -1. Put file in a preferred folder e.g. `C:\Users\Public\pairdrop-cli` -2. Search for and open `Edit environment variables for your account` -3. Click `Environment Variables…` -4. Under *System Variables* select `Path` and click *Edit...* -5. Click *New*, insert the preferred folder (`C:\Users\Public\pairdrop-cli`), click *OK* until all windows are closed -6. Reopen Command prompt window +1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases) +2. Put file in a preferred folder e.g. `C:\Program Files\pairdrop-cli` +3. Search for and open `Edit environment variables for your account` +4. Click `Environment Variables…` +5. Under *System Variables* select `Path` and click *Edit...* +6. Click *New*, insert the preferred folder (`C:\Program Files\pairdrop-cli`), click *OK* until all windows are closed +7. Reopen Command prompt window + +
+ +### Requirements +As Windows cannot execute bash scripts natively, you need to install [Git Bash](https://gitforwindows.org/). +Then, you can also use pairdrop-cli from the default Windows Command Prompt \ +by using the shell file instead of the bash file: `pairdrop.sh -h` which then itself executes \ +pairdrop-cli (the bash file) via the Git Bash. + +
+ +## Send multiple files and directories directly from context menu on Windows + +### Registering to open files with PairDrop +It is possible to send multiple files with PairDrop via the context menu by adding pairdrop-cli to Windows `Send to` menu: +1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases) +2. Unzip the archive to a folder of your choice e.g. `C:\Program Files\pairdrop-cli\` +3. Copy the shortcut _send with PairDrop.lnk_ +4. Hit Windows Key+R, type: `shell:sendto` and hit Enter. +5. Paste the copied shortcut into the directory +6. Open the properties window of the shortcut and edit the link field to point to _send-with-pairdrop.ps1_ located in the folder you used in step 2: \ + `"C:\Program Files\PowerShell\7\pwsh.exe" -File "C:\Program Files\pairdrop-cli\send-with-pairdrop.ps1"` +7. You are done! You can now send multiple files and directories directly via PairDrop: + +> _context menu > Send to > PairDrop_ + +##### Requirements +As Windows cannot execute bash scripts natively, you need to install [Git Bash](https://gitforwindows.org/). + +
+ +## Send multiple files and directories directly from context menu on Ubuntu using Nautilus + +### Registering to open files with PairDrop +It is possible to send multiple files with PairDrop via the context menu by adding pairdrop-cli to Nautilus `Scripts` menu: +1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases) +2. Unzip the archive to a folder of your choice e.g. `/usr/local/bin/pairdrop-cli/` +3. Copy the shell file _send-with-pairdrop.sh_ to `/home//.local/share/nautilus/scripts/` +4. Edit the shell file and edit the variable `pathToPairDropCli` to point to the pairdrop-cli executable from step 2 (e.g. `/usr/local/bin/pairdrop-cli/pairdrop`) +5. Make sure the shell file `/home//.local/share/nautilus/scripts/send-with-pairdrop.sh` is executable. Otherwise, use `chmod +x send-with-pairdrop.sh` +6. You are done! You can now send multiple files and directories directly via PairDrop: + +> _context menu > Scripts > send-with-pairdrop.sh_ + +
+ +## File Handling API +The [File Handling API](https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/handle-files) +was implemented, but it was removed as default file associations were overwritten ([#17](https://github.com/schlagmichdoch/PairDrop/issues/17), +[#116](https://github.com/schlagmichdoch/PairDrop/issues/116) [#190](https://github.com/schlagmichdoch/PairDrop/issues/190)) +and it only worked with explicitly specified file types and not with directories at all. [< Back](/README.md) diff --git a/docs/pairdrop_screenshot_mobile.gif b/docs/pairdrop_screenshot_mobile.gif index 1813720..1eb6eb1 100644 Binary files a/docs/pairdrop_screenshot_mobile.gif and b/docs/pairdrop_screenshot_mobile.gif differ diff --git a/licenses/BSD_3-Clause-zip-js b/licenses/BSD_3-Clause-zip-js new file mode 100644 index 0000000..4f2de22 --- /dev/null +++ b/licenses/BSD_3-Clause-zip-js @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright (c) 2023, Gildas Lormeau + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/licenses/MIT-NoSleep b/licenses/MIT-NoSleep new file mode 100644 index 0000000..fa1f83a --- /dev/null +++ b/licenses/MIT-NoSleep @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) Rich Tibbett + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/licenses/MIT-heic2any b/licenses/MIT-heic2any new file mode 100644 index 0000000..5d07689 --- /dev/null +++ b/licenses/MIT-heic2any @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2020 Alex Corvi + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/pairdrop-cli/.gitignore b/pairdrop-cli/.gitignore new file mode 100644 index 0000000..e75a6be --- /dev/null +++ b/pairdrop-cli/.gitignore @@ -0,0 +1 @@ +.pairdrop-cli-config \ No newline at end of file diff --git a/pairdrop-cli/pairdrop b/pairdrop-cli/pairdrop index b5e80bd..d9edacb 100644 --- a/pairdrop-cli/pairdrop +++ b/pairdrop-cli/pairdrop @@ -12,10 +12,12 @@ help() echo echo "Usage:" echo -e "Open PairDrop:\t\t$(basename "$0")" - echo -e "Send files:\t\t$(basename "$0") file/directory" + echo -e "Send files:\t\t$(basename "$0") file1/directory1 (file2/directory2 file3/directory3 ...)" echo -e "Send text:\t\t$(basename "$0") -t \"text\"" echo -e "Specify domain:\t\t$(basename "$0") -d \"https://pairdrop.net/\"" echo -e "Show this help text:\t$(basename "$0") (-h|--help)" + echo + echo "This pairdrop-cli version was released alongside v1.10.0" } openPairDrop() @@ -36,7 +38,7 @@ openPairDrop() elif [[ $OS == "WSL" || $OS == "WSL2" ]];then powershell.exe /c "Start-Process ${url}" else - xdg-open "$url" + xdg-open "$url" > /dev/null 2>&1 fi @@ -62,7 +64,7 @@ setOs() specifyDomain() { [[ ! $1 = http* ]] || [[ ! $1 = */ ]] && echo "Incorrect format. Specify domain like https://pairdrop.net/" && exit - echo "DOMAIN=${1}" > "$CONFIGPATH" + echo "DOMAIN=${1}" > "$config_path" echo -e "Domain is now set to:\n$1\n" } @@ -87,75 +89,228 @@ sendText() exit } +escapePSPath() +{ + local path=$1 + + # escape '[' and ']' with grave accent (`) character + pathPS=${path//[/\`[} + pathPS=${pathPS//]/\`]} + # escape single quote (') with another single quote (') + pathPS=${pathPS//\'/\'\'} + + # Convert GitHub bash path "/i/path" to Windows path "I:/path" + if [[ $pathPS == /* ]]; then + # Remove preceding slash + pathPS="${pathPS#/}" + # Convert drive letter to uppercase + driveLetter=$(echo "${pathPS::1}" | tr '[:lower:]' '[:upper:]') + # Put together absolute path as used in Windows + pathPS="${driveLetter}:${pathPS:1}" + fi + + echo "$pathPS" +} + sendFiles() { params="base64zip=hash" - if [[ $1 == */ ]]; then - path="${1::-1}" - else - path=$1 - fi - zipPath="${path}_pairdrop.zip" - zipPath=${zipPath// /_} + workingDir="$(pwd)" + tmpDir="/tmp/pairdrop-cli-temp/" + tmpDirPS="\$env:TEMP/pairdrop-cli-temp/" + + index=0 + directoryBaseNamesUnix=() + directoryPathsUnix=() + filePathsUnix=() + directoryCount=0 + fileCount=0 + pathsPS="" - [[ -a "$zipPath" ]] && echo "Cannot overwrite $zipPath. Please remove first." && exit - - if [[ -d $path ]]; then - zipPathTemp="${path}_pairdrop_temp.zip" - [[ -a "$zipPathTemp" ]] && echo "Cannot overwrite $zipPathTemp. Please remove first." && exit - echo "Processing directory..." - - # Create zip files temporarily to send directory - if [[ $OS == "Windows" ]];then - powershell.exe -Command "Compress-Archive -Path ${path} -DestinationPath ${zipPath}" - echo "Compress-Archive -Path ${zipPath} -DestinationPath ${zipPathTemp}" - powershell.exe -Command "Compress-Archive -Path ${zipPath} -DestinationPath ${zipPathTemp}" - else - zip -q -b /tmp/ -r "$zipPath" "$path" - zip -q -b /tmp/ "$zipPathTemp" "$zipPath" - fi - - if [[ $OS == "Mac" ]];then - hash=$(base64 -i "$zipPathTemp") - else - hash=$(base64 -w 0 "$zipPathTemp") - fi - - # remove temporary temp file - rm "$zipPathTemp" - else - echo "Processing file..." - - # Create zip file temporarily to send file - - if [[ $OS == "Windows" ]];then - powershell.exe -Command "Compress-Archive -Path ${path} -DestinationPath ${zipPath} -CompressionLevel Optimal" - else - zip -q -b /tmp/ "$zipPath" "$path" - fi - if [[ $OS == "Mac" ]];then - hash=$(base64 -i "$zipPath") - else - hash=$(base64 -w 0 "$zipPath") - fi + #create tmp folder if it does not exist already + if [[ ! -d "$tmpDir" ]]; then + mkdir "$tmpDir" fi - # remove temporary temp file - rm "$zipPath" + for arg in "$@"; do + echo "$arg" + [[ ! -e "$arg" ]] && echo "The given path $arg does not exist." && exit - if [[ $(echo -n "$hash" | wc -m) -gt 32600 ]];then + # Remove trailing slash from directory + arg="${arg%/}" + + # get absolute path and basename of file/directory + absolutePath=$(realpath "$arg") + baseName=$(basename "$absolutePath") + directoryPath=$(dirname "$absolutePath") + + if [[ -d $absolutePath ]]; then + # is directory + ((directoryCount+=1)) + # add basename and directory path to arrays + directoryBaseNamesUnix+=("$baseName") + directoryPathsUnix+=("$directoryPath") + else + # is file + ((fileCount+=1)) + absolutePathUnix=$absolutePath + # append new path and separate paths with space + filePathsUnix+=("$absolutePathUnix") + fi + + # Prepare paths for PowerShell on Windows + if [[ $OS == "Windows" ]];then + absolutePathPS=$(escapePSPath "$absolutePath") + + # append new path and separate paths with commas + pathsPS+="'${absolutePathPS}', " + fi + + # set fileNames on first loop + if [[ $index == 0 ]]; then + baseNameU=${baseName// /_} + + # Prevent baseNameU being empty for hidden files by removing the preceding dot + if [[ $baseNameU == .* ]]; then + baseNameU=${baseNameU#.*} + fi + + # only use trunk of basename "document.txt" -> "document" + baseNameTrunk=${baseNameU%.*} + + # remove all special characters + zipName=${baseNameTrunk//[^a-zA-Z0-9_]/} + + zipToSendAbs="${tmpDir}${zipName}_pairdrop.zip" + wrapperZipAbs="${tmpDir}${zipName}_pairdrop_wrapper.zip" + + if [[ $OS == "Windows" ]];then + zipToSendAbsPS="${tmpDirPS}${zipName}_pairdrop.zip" + wrapperZipAbsPS="${tmpDirPS}${zipName}_pairdrop_wrapper.zip" + fi + fi + + ((index+=1)) # somehow ((index++)) stops the script + done + + # Prepare paths for PowerShell on Windows + if [[ $OS == "Windows" ]];then + # remove trailing comma + pathsPS=${pathsPS%??} + fi + + echo "Preparing ${fileCount} files and ${directoryCount} directories..." + + # if arguments include files only -> zip files once so files it is unzipped by sending browser + # if arguments include directories -> wrap first zip in a second wrapper zip so that after unzip by sending browser a zip file is sent to receiver + # + # Preferred zip structure: + # pairdrop "d1/d2/d3/f1" "../../d4/d5/d6/f2" "d7/" "../d8/" "f5" + # zip structure: pairdrop.zip + # |-f1 + # |-f2 + # |-d7/ + # |-d8/ + # |-f5 + # -> truncate (relative) paths but keep directories + + [[ -e "$zipToSendAbs" ]] && echo "Cannot overwrite $zipToSendAbs. Please remove first." && exit + + if [[ $OS == "Windows" ]];then + # Powershell does preferred zip structure natively + powershell.exe -Command "Compress-Archive -Path ${pathsPS} -DestinationPath ${zipToSendAbsPS}" + else + # Workaround needed to create preferred zip structure on unix systems + # Create zip file with all single files by junking the path + if [[ $fileCount != 0 ]]; then + zip -q -b /tmp/ -j -0 -r "$zipToSendAbs" "${filePathsUnix[@]}" + fi + + # Add directories recursively to zip file + index=0 + while [[ $index < $directoryCount ]]; do + # workaround to keep directory name but junk the rest of the paths + + # cd to path above directory + cd "${directoryPathsUnix[index]}" + + # add directory to zip without junking the path + zip -q -b /tmp/ -0 -u -r "$zipToSendAbs" "${directoryBaseNamesUnix[index]}" + + # cd back to working directory + cd "$workingDir" + + ((index+=1)) # somehow ((index++)) stops the script + done + fi + + # If directories are included send as zip + # -> Create additional zip wrapper which will be unzipped by the sending browser + if [[ "$directoryCount" != 0 ]]; then + echo "Bundle as ZIP file..." + + # Prevent filename from being absolute zip path by "cd"ing to directory before zipping + zipToSendDirectory=$(dirname "$zipToSendAbs") + zipToSendBaseName=$(basename "$zipToSendAbs") + + cd "$zipToSendDirectory" + + [[ -e "$wrapperZipAbs" ]] && echo "Cannot overwrite $wrapperZipAbs. Please remove first." && exit + + if [[ $OS == "Windows" ]];then + powershell.exe -Command "Compress-Archive -Path ${zipToSendBaseName} -DestinationPath ${wrapperZipAbsPS} -CompressionLevel Optimal" + else + zip -q -b /tmp/ -0 "$wrapperZipAbs" "$zipToSendBaseName" + fi + cd "$workingDir" + + # remove inner zip file and set wrapper as zipToSend (do not differentiate between OS as this is done via Git Bash on Windows) + rm "$zipToSendAbs" + + zipToSendAbs=$wrapperZipAbs + fi + + # base64 encode zip file + if [[ $OS == "Mac" ]];then + hash=$(base64 -i "$zipToSendAbs") + else + hash=$(base64 -w 0 "$zipToSendAbs") + fi + + # remove zip file (do not differentiate between OS as this is done via Git Bash on Windows) + rm "$zipToSendAbs" + + if [[ $(echo -n "$hash" | wc -m) -gt 1000 ]];then params="base64zip=paste" + + # Copy $hash to clipboard if [[ $OS == "Windows" || $OS == "WSL" || $OS == "WSL2" ]];then echo -n "$hash" | clip.exe elif [[ $OS == "Mac" ]];then echo -n "$hash" | pbcopy + elif [ -n "$WAYLAND_DISPLAY" ]; then + # Wayland + if ! command -v wl-copy &> /dev/null; then + echo -e "You need to install 'wl-copy' to send bigger filePathsUnix from cli" + echo "Try: sudo apt install wl-clipboard" + exit 1 + fi + # Workaround to prevent use of Pipe which has a max letter limit + echo -n "$hash" > /tmp/pairdrop-cli-temp/pairdrop_hash_temp + wl-copy < /tmp/pairdrop-cli-temp/pairdrop_hash_temp + rm /tmp/pairdrop-cli-temp/pairdrop_hash_temp else - (echo -n "$hash" | xclip) || echo "You need to install xclip for sending bigger files from cli" + # X11 + if ! command -v xclip &> /dev/null; then + echo -e "You need to install 'xclip' to send bigger filePathsUnix from cli" + echo "Try: sudo apt install xclip" + exit 1 + fi + echo -n "$hash" | xclip -sel c fi hash= fi - openPairDrop exit } @@ -165,31 +320,32 @@ sendFiles() # Main program # ############################################################ ############################################################ -SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +script_path="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" pushd . > '/dev/null'; -SCRIPTPATH="${BASH_SOURCE[0]:-$0}"; +script_path="${BASH_SOURCE[0]:-$0}"; -while [ -h "$SCRIPTPATH" ]; +while [ -h "$script_path" ]; do - cd "$( dirname -- "$SCRIPTPATH"; )"; - SCRIPTPATH="$( readlink -f -- "$SCRIPTPATH"; )"; + cd "$( dirname -- "$script_path"; )"; + script_path="$( readlink -f -- "$script_path"; )"; done -cd "$( dirname -- "$SCRIPTPATH"; )" > '/dev/null'; -SCRIPTPATH="$( pwd; )"; +cd "$( dirname -- "$script_path"; )" > '/dev/null'; +script_path="$( pwd; )"; popd > '/dev/null'; -CONFIGPATH="${SCRIPTPATH}/.pairdrop-cli-config" +config_path="${script_path}/.pairdrop-cli-config" -[ ! -f "$CONFIGPATH" ] && - specifyDomain "https://pairdrop.net/" && - [ ! -f "$CONFIGPATH" ] && - echo "Could not create config file. Add 'DOMAIN=https://pairdrop.net/' to a file called .pairdrop-cli-config in the same file as this 'pairdrop' bash file" +[ ! -f "$config_path" ] && + specifyDomain "https://pairdrop.net/" && + [ ! -f "$config_path" ] && + echo "Could not create config file. Add 'DOMAIN=https://pairdrop.net/' to a file called .pairdrop-cli-config in the same file as this 'pairdrop' bash file" -[ ! -f "$CONFIGPATH" ] || export "$(grep -v '^#' "$CONFIGPATH" | xargs)" +[ ! -f "$config_path" ] || export "$(grep -v '^#' "$config_path" | xargs)" setOs + ############################################################ # Process the input options. Add options as needed. # ############################################################ @@ -198,24 +354,23 @@ setOs [[ $# -eq 0 ]] && openPairDrop && exit # display help and exit if first argument is "--help" or more than 2 arguments are given -[ "$1" == "--help" ] || [[ $# -gt 2 ]] && help && exit +[ "$1" == "--help" ] && help && exit while getopts "d:ht:*" option; do - case $option in - d) # specify domain - specifyDomain "$2" - exit;; - t) # Send text - sendText - exit;; - h | ?) # display help and exit - help - exit;; - esac + case $option in + d) # specify domain - show help and exit if too many arguments + [[ $# -gt 2 ]] && help && exit + specifyDomain "$2" + exit;; + t) # Send text - show help and exit if too many arguments + [[ $# -gt 2 ]] && help && exit + sendText + exit;; + h | ?) # display help and exit + help + exit;; + esac done # Send file(s) -# display help and exit if 2 arguments are given or if file does not exist -[[ $# -eq 2 ]] || [[ ! -a $1 ]] && help && exit - -sendFiles "$1" +sendFiles "$@" diff --git a/pairdrop-cli/pairdrop.sh b/pairdrop-cli/pairdrop.sh new file mode 100644 index 0000000..17d3672 --- /dev/null +++ b/pairdrop-cli/pairdrop.sh @@ -0,0 +1,6 @@ +#!/bin/bash +parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" || exit ; pwd -P ) + +cd "$parent_path" || exit + +./pairdrop "$@" \ No newline at end of file diff --git a/pairdrop-cli/send with PairDrop.lnk b/pairdrop-cli/send with PairDrop.lnk new file mode 100644 index 0000000..14d8fa4 Binary files /dev/null and b/pairdrop-cli/send with PairDrop.lnk differ diff --git a/pairdrop-cli/send-with-pairdrop.ps1 b/pairdrop-cli/send-with-pairdrop.ps1 new file mode 100644 index 0000000..cfb11b0 --- /dev/null +++ b/pairdrop-cli/send-with-pairdrop.ps1 @@ -0,0 +1,3 @@ +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path + +& "$scriptDir\pairdrop.sh" $args \ No newline at end of file diff --git a/pairdrop-cli/send-with-pairdrop.sh b/pairdrop-cli/send-with-pairdrop.sh new file mode 100644 index 0000000..194beac --- /dev/null +++ b/pairdrop-cli/send-with-pairdrop.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# edit this to point to the pairdrop-cli executable +pathToPairDropCli="/usr/local/bin/pairdrop-cli/pairdrop" + +# Initialize an array +lines=() + +# Read each line into the array +while IFS= read -r line; do + lines+=("$line") +done <<< "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" + +# Get the length of the array +length=${#lines[@]} + +# Remove the last entry +unset 'lines[length-1]' + +$pathToPairDropCli "${lines[@]}" \ No newline at end of file diff --git a/public/images/android-chrome-192x192-maskable.png b/public/images/android-chrome-192x192-maskable.png index de6b81b..7a70b20 100644 Binary files a/public/images/android-chrome-192x192-maskable.png and b/public/images/android-chrome-192x192-maskable.png differ diff --git a/public/images/android-chrome-192x192.png b/public/images/android-chrome-192x192.png index ea419d4..217e355 100644 Binary files a/public/images/android-chrome-192x192.png and b/public/images/android-chrome-192x192.png differ diff --git a/public/images/android-chrome-512x512-maskable.png b/public/images/android-chrome-512x512-maskable.png index f2253c7..b0e9ee5 100644 Binary files a/public/images/android-chrome-512x512-maskable.png and b/public/images/android-chrome-512x512-maskable.png differ diff --git a/public/images/android-chrome-512x512.png b/public/images/android-chrome-512x512.png index da6f1c8..0dc0647 100644 Binary files a/public/images/android-chrome-512x512.png and b/public/images/android-chrome-512x512.png differ diff --git a/public/images/favicon-96x96-notification.png b/public/images/favicon-96x96-notification.png index 3b1d846..54cbbf6 100644 Binary files a/public/images/favicon-96x96-notification.png and b/public/images/favicon-96x96-notification.png differ diff --git a/public/images/favicon-96x96.png b/public/images/favicon-96x96.png index c884154..3ed2446 100644 Binary files a/public/images/favicon-96x96.png and b/public/images/favicon-96x96.png differ diff --git a/public/images/logo_blue_512x512.png b/public/images/logo_blue_512x512.png index f2253c7..b0e9ee5 100644 Binary files a/public/images/logo_blue_512x512.png and b/public/images/logo_blue_512x512.png differ diff --git a/public/images/logo_transparent_white_512x512.png b/public/images/logo_transparent_white_512x512.png index 37589b6..2c9d046 100644 Binary files a/public/images/logo_transparent_white_512x512.png and b/public/images/logo_transparent_white_512x512.png differ diff --git a/public/images/mstile-150x150.png b/public/images/mstile-150x150.png index 6380e32..945d874 100644 Binary files a/public/images/mstile-150x150.png and b/public/images/mstile-150x150.png differ diff --git a/public/images/pairdrop_screenshot_mobile_1.png b/public/images/pairdrop_screenshot_mobile_1.png index d93aafb..42aae56 100644 Binary files a/public/images/pairdrop_screenshot_mobile_1.png and b/public/images/pairdrop_screenshot_mobile_1.png differ diff --git a/public/images/pairdrop_screenshot_mobile_2.png b/public/images/pairdrop_screenshot_mobile_2.png index 51ace10..c472c33 100644 Binary files a/public/images/pairdrop_screenshot_mobile_2.png and b/public/images/pairdrop_screenshot_mobile_2.png differ diff --git a/public/images/pairdrop_screenshot_mobile_3.png b/public/images/pairdrop_screenshot_mobile_3.png index 57ad15a..0a61028 100644 Binary files a/public/images/pairdrop_screenshot_mobile_3.png and b/public/images/pairdrop_screenshot_mobile_3.png differ diff --git a/public/images/pairdrop_screenshot_mobile_4.png b/public/images/pairdrop_screenshot_mobile_4.png index d5811ad..4b442d5 100644 Binary files a/public/images/pairdrop_screenshot_mobile_4.png and b/public/images/pairdrop_screenshot_mobile_4.png differ diff --git a/public/images/pairdrop_screenshot_mobile_5.png b/public/images/pairdrop_screenshot_mobile_5.png index d205fd9..5d0682f 100644 Binary files a/public/images/pairdrop_screenshot_mobile_5.png and b/public/images/pairdrop_screenshot_mobile_5.png differ diff --git a/public/images/pairdrop_screenshot_mobile_6.png b/public/images/pairdrop_screenshot_mobile_6.png index 23c06ae..c4a1e1d 100644 Binary files a/public/images/pairdrop_screenshot_mobile_6.png and b/public/images/pairdrop_screenshot_mobile_6.png differ diff --git a/public/images/pairdrop_screenshot_mobile_7.png b/public/images/pairdrop_screenshot_mobile_7.png index c32980a..b1dc8ad 100644 Binary files a/public/images/pairdrop_screenshot_mobile_7.png and b/public/images/pairdrop_screenshot_mobile_7.png differ diff --git a/public/images/pairdrop_screenshot_mobile_8.png b/public/images/pairdrop_screenshot_mobile_8.png new file mode 100644 index 0000000..7532227 Binary files /dev/null and b/public/images/pairdrop_screenshot_mobile_8.png differ diff --git a/public/index.html b/public/index.html index e6fa076..317a4cc 100644 --- a/public/index.html +++ b/public/index.html @@ -40,7 +40,7 @@ -
+
@@ -95,20 +95,49 @@ - +
-
- - + +

- -

-
+ +