[![tests](https://github.com/Shiphero/shbin/actions/workflows/pytest.yml/badge.svg?branch=main)](https://github.com/Shiphero/shbin/actions/workflows/pytest.yml) [![black](https://github.com/Shiphero/shbin/actions/workflows/black.yml/badge.svg?branch=main)](https://github.com/Shiphero/shbin/actions/workflows/black.yml) [![PyPI version](https://img.shields.io/pypi/v/shbin)](https://pypi.org/project/shbin/) [![PyPI - Downloads](https://img.shields.io/pypi/dm/shbin)](https://libraries.io/pypi/shbin) `shbin` turns a Github repo into a pastebin. It's a tiny command-line tool we've built at [Shiphero](http://shiphero.com) that lets you easily upload code snippets, notebooks, images or any other content to a Github repository that acts as your internal pastebin, and returns the URL to share it with your team. If possible, this URL is automatically copied to the clipboard.

# Why? You want to share code snippets, images, notebooks, etc. with your team, probably privately. Gist is great, but it has some limitations: - The content may be secret but it is not private: if you have the url you have the access (and to err is human). - The ownership of the shared content is in the user's namespace, not the organization's. What happens if the user leaves the organization? - You can't find some secret content shared by a teammate if the URL is lost. Only the person who created it can find it, and even that isn't easy if the content doesn't have a good name and description. - Content organization is difficult: you can upload multiple files to a gist, but you can't create folders. - The default gist interface does not allow you to "paste" an image (you can paste it as part of a comment, but not as part of the gist content itself). Sharing screenshots is a common use case on computers. Using a full repository has all the advantages of Gist (rich content rendering like markdown or ipynb, every change is a git commit, etc.) without these limitations. The only downside of a plain repository is that it is not as easy as "paste" the content, even when editing through the Github interface. But `shbin` solves that. Sound good? Give us a star and share it! [![Sparkline](https://stars.medv.io/shiphero/shbin.svg)](https://stars.medv.io/shiphero/shbin) # Usage ```console # upload or update a file $ shbin demo.py # upload with a commit description $ shbin demo.py -m "my cool demo script" # Upload any content in clipboard, discovering its format. e.g. # a screenshot. The name will be random but the extension will be # based on the format detected. $ shbin -x # upload the content in the clipboard with a given filename $ shbin -x -f my_snippet.md # upload from stdin $ echo "some content" | shbin - # download a given file (inside the namespace) $ shbin dl my_snippet.md # update the content of a file that already exists $ shbin my_snippet.md # from clipboard with a given name to a directory in your user directory $ shbin -x -f the_coolest_thing.py -d coolest_things/python # upload several files in a directory $ shbin *.ipynb *.csv -d notebooks/project -m "my new work" # Reformat the URL to link to Github pages. $ shbin demo.py -p $ shbin -h # show full options ``` # How it works It uses [Github API](https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28#create-or-update-file-contents) to create or update files in the given repo. So there is no need to have the target repository fully cloned locally. # Install The recommended way is to use [uv](https://docs.astral.sh/uv/) ```console uv tool install shbin ``` To install the latest development version from the repository: ```console uv tool install https://github.com/Shiphero/shbin/archive/refs/heads/main.zip ``` ## OSX shbin depends on [python-magic](https://github.com/ahupp/python-magic#osx). This can be installed as follows. - When using Homebrew: ```console brew install libmagic ``` - When using macports: ```console port install file ``` # Setup To authenticate, simply run: ``` shbin init ``` This command will guide you through creating a token and and selecting a repository, then store them locally so that `shbin` can use them right away. Alternatively, you can **manually** create a [new fine-grained personal token](https://github.com/settings/personal-access-tokens/new) on Github restricted to your "pastebin" repository (under your user or your organization's ownership), with **read and write** permission on **Contents**: ![image](https://user-images.githubusercontent.com/2355719/238758491-9d15e7e6-e4b7-43c8-a321-b65c968fc7e0.png) Then set the environment variables: ``` export SHBIN_GITHUB_TOKEN="" export SHBIN_REPO="/" # example "myorg/pastebin" ``` By default `shbin` assigns a top-level folder to separate the content uploaded by each user. This can be changed using the `SHBIN_NAMESPACE` environment variable or the `--namespace` argument from the command line. For example: - `export SHBIN_NAMESPACE=""` # no namespace - `export SHBIN_NAMESPACE="pastebin_folder"` # the full pastebin is inside pastebin_folder/" - `export SHBIN_NAMESPACE="pastebin_folder/{user}"` # mix of both: each user has its own subfolder inside `pastebin_folder/` > [!NOTE] > To interact with the clipboard, we use the library `pyclip`. This may require some additional system > dependencies depending your operating system. See [these notes](https://github.com/spyoungtech/pyclip#platform-specific-notesissues). > If you want to disable the automatic copying of the URL to the clipboard > you can set the environment variable `SHBIN_COPY_URL=false` (or "0" or "no"). > > This is useful in some Linux distributions that use Wayland as the call via `wl-copy` > that `pyclip` uses in such environment can be slow. Nice video courtesy of [tuterm](https://github.com/veracioux/tuterm), [asciinema](https://asciinema.org/) and [svg-term-cli](https://github.com/marionebl/svg-term-cli) PRs are welcome!