github.com/4thel00z/pcopy@v0.0.0-20230830212547-a1758a3a86bc/README.md (about)

     1  # pcopy
     2  
     3  ----
     4  
     5  ## Disclaimer
     6  
     7  This is a fork of [pcopy](https://github.com/binwiederhier/pcopy) from Phillip C. Heckel who is a nice guy.
     8  
     9  The modifications on this fork, enable the server to be run behind a revery proxy like caddy with basicauth enabled.
    10  
    11  ----
    12  
    13  [![Release](https://img.shields.io/github/release/4thel00z/pcopy.svg?color=success&style=flat-square)](https://github.com/4thel00z/pcopy/releases/latest)
    14  [![Go Reference](https://pkg.go.dev/badge/github.com/4thel00z/pcopy.svg)](https://pkg.go.dev/github.com/4thel00z/pcopy)
    15  [![Tests](https://github.com/4thel00z/pcopy/workflows/test/badge.svg)](https://github.com/4thel00z/pcopy/actions)
    16  [![Go Report Card](https://goreportcard.com/badge/github.com/4thel00z/pcopy)](https://goreportcard.com/report/github.com/4thel00z/pcopy)
    17  [![codecov](https://codecov.io/gh/4thel00z/pcopy/branch/master/graph/badge.svg?token=bdrFZttMsk)](https://codecov.io/gh/4thel00z/pcopy)
    18  [![Slack channel](https://img.shields.io/badge/slack-@gophers/pcopy-success.svg?logo=slack)](https://gophers.slack.com/archives/C01JMTPGF2Q)
    19  
    20  pcopy is a tool to copy/paste across machines. It can be used from the [web UI](#web-ui-for-uploading-text-snippets-or-large-files),
    21  via a CLI or without a client by using curl. It can also be used as a self-hosted NoPaste or as a temporary file hosting service.
    22  
    23  After installing the pcopy server, you can use the `pcopy` command line tool to copy from STDIN (`pcp < file.txt`) and 
    24  paste on any connected machine to STDOUT (`ppaste > file.txt`). If you don't have pcopy installed, you can also use its
    25  super simple REST API to copy/paste, e.g. via `curl`.
    26  
    27  The web UI allows you to paste text or upload files (even if they are gigabytes in size), and generates 
    28  temporary links you can share with others. 
    29  
    30  To see what else pcopy can do, check out the **[live demo](#demo)** (aka [nopaste.net](https://nopaste.net)) or the **[videos](#videos)**.
    31  
    32  **Features:**
    33  * 📋 Copy/paste across computers (via STDIN/STDOUT)
    34  * 🔒 HTTPS secure server (via cert-pinning)
    35  * 🔑 Clipboards can be [password-protected](#password-protected-clipboard), or they can be open for everyone
    36  * 📚 Support for [multiple clipboards](#support-for-multiple-clipboards) (e.g. personal, work, ...)
    37  * 🌎 Simple [Web UI](#web-ui-for-uploading-text-snippets-or-large-files) for uploading text snippets or large files
    38  * 🔗 Direct [temporary links](#direct-temporary-links-to-clipboard-content-with-ttlexpiration) to clipboard content (with TTL/expiration) 
    39  * 💻 No-install usage via [curl](#curl-compatible-usage) (`curl nopaste.net`) and [netcat](#nc-compatible-usage) (`echo help | nc -N nopaste.net 9999`)
    40  * 👁️ [Browser-only links](#browser-only-links-that-store-your-data-in-the-url-fragment) that store your data in the URL fragment 
    41  
    42  ![pcopy demo](assets/demo-simple.gif)
    43  
    44  ## Installation
    45  Binaries can be found on the [releases page](https://github.com/4thel00z/pcopy/releases). 
    46  
    47  **Debian/Ubuntu** (*from a repository*)**:**   
    48  ```bash
    49  curl -sSL https://archive.github.com/4thel00z/pcopy/apt/pubkey.txt | sudo apt-key add -
    50  sudo apt install apt-transport-https
    51  sudo sh -c "echo 'deb [arch=amd64] https://archive.github.com/4thel00z/pcopy/apt debian main' > /etc/apt/sources.list.d/archive.github.com/4thel00z/pcopy.list"  
    52  sudo apt update
    53  sudo apt install pcopy
    54  ```
    55  
    56  **Debian/Ubuntu** (*manual install*)**:**
    57  ```bash
    58  wget https://github.com/4thel00z/pcopy/releases/download/v0.6.1/pcopy_0.6.1_amd64.deb
    59  dpkg -i pcopy_0.6.1_amd64.deb
    60  ```
    61  
    62  **Fedora/RHEL/CentOS:**
    63  ```bash
    64  rpm -ivh https://github.com/4thel00z/pcopy/releases/download/v0.6.1/pcopy_0.6.1_amd64.rpm
    65  ```
    66  
    67  **Homebrew for MacOS:**
    68  Brew package is managed semi-automatically by [nwithan8](https://github.com/nwithan8/homebrew-tap)
    69  ```bash
    70  brew tap nwithan8/tap
    71  brew install pcopy
    72  ```
    73  
    74  **Docker** (*see [detailed instructions](#docker-usage)*)**:**
    75  ```bash
    76  docker run --rm -it ransomwarezz/pcopy
    77  ```
    78  
    79  **Go:**
    80  ```bash
    81  # requires Go 1.16
    82  go get -u github.com/4thel00z/pcopy
    83  ```
    84  
    85  **Manual install** (*any x86_64-based Linux*)**:**
    86  ```bash
    87  wget https://github.com/4thel00z/pcopy/releases/download/v0.6.1/pcopy_0.6.1_linux_x86_64.tar.gz
    88  sudo tar -C /usr/bin -zxf pcopy_0.6.1_linux_x86_64.tar.gz pcopy
    89  ```
    90  
    91  After installation, you may want to check out the [Bash/ZSH autocomplete instructions](#bashzsh-autocompletion).
    92  
    93  ## Usage
    94  
    95  ### Set up a pcopy server
    96  To setup a new pcopy server, simply run `sudo pcopy setup` (see [server setup demo](#videos)): 
    97  ```bash
    98  sudo pcopy setup
    99  sudo systemctl enable pcopy
   100  sudo systemctl start pcopy
   101  ```
   102  This will walk you through an interactive setup wizard and place a config file at `/etc/pcopy/server.conf` (see 
   103  [sample config](configs/pcopy.conf)). The wizard will set up a pcopy user and a systemd service. Once the service 
   104  is started, it listens on port 2586 by default.
   105  
   106  If you've enabled the Web UI, you can browse to it an paste text snippets or upload files to it (see [live demo](#demo)).    
   107  
   108  ### Join an existing clipboard
   109  To join an existing clipboard, you may use `pcopy join`:
   110  ```bash
   111  pcopy join private.example.com
   112  pcopy join work.mycorp.com work
   113  pcopy list
   114  ```
   115  You can join multiple clipboards and give each of them an optional alias (see `work` clipboard above). Each 
   116  clipboard has its own config file, either in `~/.config/pcopy` or in `/etc/pcopy` (for root). You can list connected
   117  clipboards with `pcopy list`.
   118  
   119  ### Start copying & pasting
   120  Now you can start copying and pasting by using `pcp` (short for: `pcopy copy`) and `ppaste` (short for: `pcopy paste`). 
   121  Any connected client, regardless of what computer it's on, can copy/paste like this (see [copy/pasting videos](#videos)):
   122  
   123  ```bash
   124  pcp < foo.txt            # Copies foo.txt to the default clipboard
   125  pcp bar < bar.txt        # Copies bar.txt to the default clipboard as 'bar'
   126  echo hi | pcp work:      # Copies 'hi' to the 'work' clipboard
   127  echo ho | pcp work:bla   # Copies 'ho' to the 'work' clipboard as 'bla'
   128  pcp : img1/ img2/        # Creates ZIP from two folders, copies it to the clipboard
   129  
   130  ppaste                   # Reads from the default clipboard and prints its contents
   131  ppaste bar > bar.txt     # Reads 'bar' from the default clipboard to file 'bar.txt'
   132  ppaste work:             # Reads from the 'work' clipboard and prints its contents
   133  ppaste work:ho > ho.txt  # Reads 'ho' from the 'work' clipboard to file 'ho.txt'
   134  ppaste : images/         # Extracts ZIP from default clipboard to folder images/
   135  ```
   136  
   137  ## Advanced features
   138  The server can be configured via the well-documented config file `/etc/pcopy/server.conf` (see [sample config](configs/pcopy.conf)).
   139  Here are a few highlights:
   140  
   141  ### Password-protected clipboard 
   142  When you set up a new clipboard via `pcopy setup`, you can enter a password. That derives a key, which is stored in the 
   143  config file (see [Key section](https://github.com/4thel00z/pcopy/blob/4dfeb5b8647c04cc54aa1538b8fb3f5d384c3700/configs/pcopy.conf#L23-L30)).
   144  To add a password after initial setup, use the `pcopy keygen` command.
   145  
   146  When joining a clipboard with `pcopy join`, you'll be asked for a password. When using `curl`, you can provide the 
   147  password via `-u :<password>` (see [curl usage](#curl-compatible-usage)). 
   148  
   149  ### Support for multiple clipboards
   150  You can provide an (optional) alias to a clipboard when you `pcopy join` it (see [join](#join-an-existing-clipboard)).
   151  You may then later reference that alias in `pcp <alias>:..` and `ppaste <alias>:..` (see [copy/paste](#start-copying--pasting)).
   152  
   153  To list all your connected clipboards, simple type:
   154  ```bash
   155  $ pcopy list
   156  Clipboard Server address   Config file
   157  --------- --------------- ----------------------------
   158  work      10.0.160.67     ~/.config/pcopy/work.conf
   159  default   nopaste.net:443 ~/.config/pcopy/default.conf
   160  ```
   161  ### Web UI for uploading text snippets or large files
   162  pcopy comes with a Web UI. You can check out the [demo](#demo).   
   163  *(Note: I am not a web guy. I could use some help here!)*
   164  
   165  ![Web UI](assets/demo-webui.gif)
   166  
   167  ### `curl`-compatible usage 
   168  If you don't want to install `pcopy` on a server, you can use simple HTTP GET/PUT/POSTs, e.g. via `curl`. There's an entire
   169  `curl` [help page](https://nopaste.net/curl) available too if you just type `curl <hostname>`. You may use `-u :<password>` to provide the clipboard
   170   password (if any). Here's an example for the [demo clipboard](#demo):
   171  ```bash
   172  # Show curl help page
   173  curl nopaste.net
   174  
   175  # Copy/upload to clipboard (POST/PUT both work)
   176  curl -d Howdy nopaste.net/hi-there
   177  curl -T germany.jpg https://nopaste.net/germany
   178  
   179  # Paste/download from clipboard
   180  curl https://nopaste.net/hi-there
   181  ```
   182  
   183  ### `nc`-compatible usage 
   184  Similar to the `curl` API, you can upload files via netcat (`nc`). There's a detailed [help page](https://nopaste.net/nc) available by typing `echo help | nc <hostname> <port>`, e.g. `echo help | nc -N nopaste.net 9999`. Unlike the curl-API, the netcat usage is limited to uploading files only.
   185  
   186  ```bash
   187  # Show nc help page
   188  echo help | nc -N nopaste.net 9999
   189  
   190  # Upload to clipboard
   191  echo check this out | nc -N nopaste.net 9999
   192  cat dog.jpg | nc -N nopaste.net 9999
   193  
   194  # Upload with  TTL
   195  (echo "pcopy:?t=30m"; cat dog.jpg) | nc -N nopaste.net 9999
   196  ```
   197  
   198  ### Streaming contents (without storing them on server)
   199  If you have particularly large files to send across, and you know you only want to send them to exactly one server,
   200  you can use ` pcp --stream`. It creates a FIFO device (`mkfifo`) on the server side, and will wait until a reading
   201  client (`ppaste` or `curl ..`) is connected before sending.
   202  
   203  ```bash
   204  # On machine 1
   205  yes | pcp --stream    # Will block until 'machine 2' is connected
   206  
   207  # On machine 2
   208  ppaste | pv > /dev/null
   209  ``` 
   210  
   211  ### Direct temporary links to clipboard content (with TTL/expiration)
   212  You can generate temporary links to clipboard entries with `pcopy link`. You can send this link to someone and they
   213  can download the clipboard content without downloading the client or using any command line tools:
   214  
   215  ```bash
   216  $ pcopy link hi-there
   217  # Direct link (valid for 2d, expires 2021-01-29 22:35:09 -0500 EST)
   218  https://nopaste.net/hi-there?a=SE1BQyA
   219  
   220  # Paste via pcopy (you may need a prefix)
   221  ppaste hi-there 
   222  
   223  # Paste via curl
   224  curl -sSL 'https://nopaste.net/hi-there?a=SE1BQyAxNjA'
   225  ```
   226  
   227  ### Limiting clipboard usage
   228  You can limit the clipboard usage in various ways in the config file (see [config file](https://github.com/4thel00z/pcopy/blob/4dfeb5b8647c04cc54aa1538b8fb3f5d384c3700/configs/pcopy.conf#L66-L101)), 
   229  to avoid abuse:
   230  
   231  * `ClipboardSizeLimit`: Limits the total size of the entire clipboard (size of all files)
   232  * `ClipboardCountLimit`: Limits the number of clipboard files
   233  * `FileSizeLimit`: Limits the per-file size
   234  * `FileExpireAfter`: Limits the age of a file (after which they will be deleted)
   235  
   236  The [demo clipboard](#demo) uses these settings very restrictively to avoid abuse.
   237  
   238  ### Browser-only links that store your data in the URL fragment
   239  
   240  Inspired by [nopaste.ml](https://nopaste.ml) and [paste](https://github.com/topaz/paste), pcopy also supports links that 
   241  store all data in the URL fragment/anchor (the part in the URL after the `#`) and not on the server. 
   242  
   243  When the "Client-side" checkbox is checked in the Web UI, pcopy compresses the text in the editor using LZMA and then 
   244  encodes the result using Base64, e.g. `https://nopaste.net/#XQAAAQAKAA...`. As long as you have this link, this text can
   245  never be deleted and never expires.
   246  
   247  Here's an [example](https://nopaste.net/#XQAAAQD/AAAAAAAAAAAkGkAHQ30IXZA3jeQkZZItfPikpd4KaJ5EwL+3jkWf1npuHdpK3Miq3nr2jWTqjzbcQcfEp1beN+JG4OrP2U1B05NIVqx4SK5oEeVjzYaQ7c+ZeI6M28viSMa1/EwPhNjrfvPpa8sNufdVJxUtZX1KphQKpZwAO5ShztZNvnpvpsf2KTtyHw6z4Ybm/nBAKzuJF3fCz1qTnAuGTHA91Kp0s7GbEBP5bGgGNSsqaWesKd9AE59x0Uf27+z+dRdxLev/9U/BQw==). 
   248  When you open the link, pcopy reads, decodes, and decompresses whatever is after the `#`, and displays the result in the editor.
   249  This process is done entirely in your browser, and the web server hosting pcopy never has access to the fragment.
   250  
   251  The link is also compatible with the original implementations. Here's the same example for [nopaste.ml](https://nopaste.ml/#XQAAAQD/AAAAAAAAAAAkGkAHQ30IXZA3jeQkZZItfPikpd4KaJ5EwL+3jkWf1npuHdpK3Miq3nr2jWTqjzbcQcfEp1beN+JG4OrP2U1B05NIVqx4SK5oEeVjzYaQ7c+ZeI6M28viSMa1/EwPhNjrfvPpa8sNufdVJxUtZX1KphQKpZwAO5ShztZNvnpvpsf2KTtyHw6z4Ybm/nBAKzuJF3fCz1qTnAuGTHA91Kp0s7GbEBP5bGgGNSsqaWesKd9AE59x0Uf27+z+dRdxLev/9U/BQw==)
   252  and for [topaz's paste](https://topaz.github.io/paste/#XQAAAQD/AAAAAAAAAAAkGkAHQ30IXZA3jeQkZZItfPikpd4KaJ5EwL+3jkWf1npuHdpK3Miq3nr2jWTqjzbcQcfEp1beN+JG4OrP2U1B05NIVqx4SK5oEeVjzYaQ7c+ZeI6M28viSMa1/EwPhNjrfvPpa8sNufdVJxUtZX1KphQKpZwAO5ShztZNvnpvpsf2KTtyHw6z4Ybm/nBAKzuJF3fCz1qTnAuGTHA91Kp0s7GbEBP5bGgGNSsqaWesKd9AE59x0Uf27+z+dRdxLev/9U/BQw==).
   253  
   254  You can also generate the links from the command line (thanks to nopaste.ml for this):
   255  ```
   256  # Linux
   257  echo -n 'Hello World' | lzma | base64 -w0 | xargs -0 printf "https://nopaste.net/#%s\n"
   258  
   259  # Mac
   260  echo -n 'Hello World' | lzma | base64 | xargs -0 printf "https://nopaste.net/#%s\n"
   261  
   262  # Windows / WSL / Linux
   263  echo -n 'Hello World' | xz --format=lzma | base64 -w0 | printf "https://nopaste.net/#%s\n" "$(cat -)"
   264  ```
   265  
   266  ### Docker usage
   267  To use the [pcopy image](https://hub.docker.com/r/4thel00z/pcopy), simply pull it and set up a few 
   268  shell aliases to simplify local usage: 
   269  
   270  ```bash
   271  docker pull ransomwarezz/pcopy
   272  alias pcopy="docker run --rm -v ~/.cache/pcopy:/var/cache/pcopy -v ~/.config/pcopy:/etc/pcopy -p 2586:2586/tcp -it ransomwarezz/pcopy"
   273  alias pcp="pcopy copy"
   274  alias ppaste="pcopy paste"
   275  ```
   276  
   277  This maps the following folders and ports (you may choose different host folders):
   278  * Config folder: `/etc/pcopy` (image) to `~/.config/pcopy` (host)
   279  * Clipboard folder (only for server usage): `/var/cache/pcopy` (image) to `~/.cache/pcopy` (host)
   280  * Service port (only for server usage): 2586 (both image and host) 
   281  
   282  You can then use pcopy just like it was installed on your host system. To use it as a client, run 
   283  `pcopy join` (see [join instructions](#join-an-existing-clipboard)). To set up a server, run
   284  
   285  ```bash
   286  pcopy setup
   287  pcopy serve
   288  ```
   289  
   290  ### Bash/ZSH autocompletion
   291  Tab completion is available for Bash and ZSH. For Bash, when installed via rpm/deb, autocomplete is immediately
   292  available. ZSH autocomplete installation is manual.
   293  
   294  **Bash** (*only if not installed via rpm/deb*):
   295  ```
   296  sudo wget -O /etc/bash_completion.d/pcopy https://raw.githubusercontent.com/4thel00z/pcopy/master/scripts/autocomplete_bash
   297  sudo ln -s /etc/bash_completion.d/pcopy /etc/bash_completion.d/pcp
   298  sudo ln -s /etc/bash_completion.d/pcopy /etc/bash_completion.d/ppaste
   299  ```
   300  
   301  **ZSH**:
   302  ```
   303  mkdir -p ~/.config/pcopy
   304  wget -O ~/.config/pcopy/autocomplete_zsh https://raw.githubusercontent.com/4thel00z/pcopy/master/scripts/autocomplete_zsh
   305  for p in pcopy pcp ppaste; do echo "PROG=$p source ~/.config/pcopy/autocomplete_zsh" >> ~/.zshrc; done
   306  ```
   307  
   308  ## Demo
   309  I run a small nopaste service on **[nopaste.net](https://nopaste.net)** that you can play with. It has quite a few 
   310  limits in place, but you'll be able to get a feel for it:
   311  
   312  - To join via the command line: `pcopy join nopaste.net` (see [join instructions](#join-an-existing-clipboard))
   313  - Or use the [web UI](https://nopaste.net) (this is *work in progress*, I'm not a web designer, please help!)
   314  - Or simply type `curl nopaste.net` (see [curl usage](#curl-compatible-usage)) 
   315  - Or simply type `echo help | nc -N nopaste.net 9999` (see [netcat usage](#nc-compatible-usage)) 
   316  
   317  **Limits:**   
   318  Since [nopaste.net](https://nopaste.net) is publicly available, I put quite strict limits in place. It is limited to 
   319  2 GB total, 500 KB per file, 10,000 files. Files expire after 2 days. Also, overwriting files is disabled (which, if
   320  you use it as a personal clipboard, is quite nonesensical, but it makes sense for a nopaste).
   321  
   322  I also made a couple [more videos](#videos) to show what else pcopy can do.
   323  
   324  ## Videos
   325  
   326  <table>
   327    <tr>
   328      <td><img src="assets/demo-simple.gif" width="300"></td>
   329      <td><img src="assets/demo-setup.gif" width="300"></td>
   330      <td><img src="assets/demo-zip.gif" width="300"></td>
   331    </tr>
   332    <tr>
   333      <td>Simple copy & paste</td>
   334      <td>Setting up a new server</td>
   335      <td>Copying entire folders</td>
   336    </tr>
   337    <tr>
   338      <td><img src="assets/demo-link.gif" width="300"></td>    
   339      <td><img src="assets/demo-webui.gif" width="300"></td>
   340      <td><img src="assets/demo-curl.gif" width="300"></td>
   341      <td></td>
   342    </tr>
   343    <tr>
   344      <td>Creating a link to a password-protected clipboard</td>        
   345      <td>Copying/uploading through the Web UI</td>
   346      <td>Copy/pasting with `curl`</td>
   347      <td></td>
   348    </tr>
   349  </table>
   350  
   351  ## Command-line help
   352  Each command has a detailed help page. Simply type `pcopy -help`, `pcp -help`, etc. Here's the main help page:
   353  ```bash 
   354  $ pcopy --help
   355  NAME:
   356     pcopy - copy/paste across machines
   357  
   358  USAGE:
   359     pcopy COMMAND [OPTION..] [ARG..]
   360  
   361  COMMANDS:
   362     Client-side commands:
   363       copy, c    Read from STDIN/file(s) and copy to remote clipboard
   364       paste, p   Write remote clipboard contents to STDOUT/file(s)
   365       join, add  Join a remote clipboard
   366       leave, rm  Leave a remote clipboard
   367       list, l    Lists all of the clipboards that have been joined
   368       link, n    Generate direct download link to clipboard content
   369     Server-side commands:
   370       serve   Start pcopy server
   371       setup   Initial setup wizard for a new pcopy server
   372       keygen  Generate key for the server config
   373  
   374  Try 'pcopy COMMAND --help' for more information.
   375  ``` 
   376  
   377  ## Building
   378  Building pcopy is dead simple, however it does need Go >=1.16, because it uses [embed](https://tip.golang.org/pkg/embed/). 
   379  Here's how you build it:
   380  
   381  ```
   382  make build-simple
   383  # Builds to dist/pcopy_linux_amd64/pcopy
   384  ``` 
   385  
   386  To build releases, I use [GoReleaser](https://goreleaser.com/). If you have that installed, you can run `make build` or 
   387  `make build-snapshot`.
   388  
   389  ## Contributing
   390  I welcome any and all contributions. Just create a PR or an issue, or talk to me [on Slack](https://gophers.slack.com/archives/C01JMTPGF2Q).
   391  
   392  ## Inspired by
   393  Thanks [nakabonne](https://github.com/nakabonne) for making [pbgopy](https://github.com/nakabonne/pbgopy), and for 
   394  [posting it on Reddit](https://www.reddit.com/r/golang/comments/k2nzyn/pbgopy_copy_and_paste_between_devices/gdwpy8u/?context=3). 
   395  It inspired me to make pcopy. 
   396  
   397  The Web UI as well as the client-side mode are inspired by [nopaste.ml](https://nopaste.ml/).
   398  
   399  As many may instantly notice, pcopy is similar to [pbcopy/pbpaste](https://osxdaily.com/2007/03/05/manipulating-the-clipboard-from-the-command-line/). 
   400  However, pcopy can copy/paste across the network. You can copy on your laptop and paste on your servers.
   401  
   402  pcopy may also replace [scp](https://linux.die.net/man/1/scp) or [rsync](https://linux.die.net/man/1/rsync) in simple cases,
   403  when you just want to copy a file or folder across to another computer. 
   404  
   405  ## License
   406  Made with ☕ by [4thel00z](https://github.com/4thel00z/pcopy), distributed under the [Apache License 2.0](LICENSE).
   407  
   408  Third party libraries:
   409  * [github.com/urfave/cli/v2](https://github.com/urfave/cli/v2) (MIT) is used to drive the CLI
   410  * [CryptoJS](https://github.com/brix/crypto-js) (MIT) is used for key derivation and such in the Web UI
   411  * [LZMA-JS](https://github.com/LZMA-JS/LZMA-JS) (MIT) is used for client-side mode to compress text
   412  * [Lato Font](https://www.latofonts.com/) (OFL) is used as a font in the Web UI
   413  * [GoReleaser](https://goreleaser.com/) (MIT) is used to create releases 
   414  
   415  Code and posts that helped:
   416  * [Drag & Drop](https://stackoverflow.com/a/33917000/1440785) (CC BY-SA 3.0)
   417  * [Progress indicator](https://github.com/machinebox/progress) (Apache 2.0)
   418  * [Rate limiting](https://www.alexedwards.net/blog/how-to-rate-limit-http-requests) (MIT)
   419  * [Find common directory](https://rosettacode.org/wiki/Find_common_directory_path#Go) (GFDLv1.2)
   420  * [Full page centering](https://medium.com/creative-technology-concepts-code/full-page-site-with-vertical-centering-using-css-only-7858ed6764c4)
   421  * [Human readable file sizes](https://yourbasic.org/golang/formatting-byte-size-to-human-readable-format/)
   422  * [Unzipping files](https://golangcode.com/unzip-files-in-go/)
   423  * [HTTP server routing](https://benhoyt.com/writings/go-routing/#regex-table)
   424  * [HTTP server error handling](https://thingsthatkeepmeupatnight.dev/posts/golang-http-handler-errors/)
   425  * [Google Webfonts Helper](https://google-webfonts-helper.herokuapp.com/)