# ssky - Simple Bluesky client
## Introduction
Ssky is a simple Bluesky client, providing some specific features.
* Simple but Linux shell friendly user interface
* You can give `URI` or `URI::CID` to retrieve (get), quote, reply-to, repost/unrepost and delete a unique post
* You can give `DID` or `handle` to retrieve timeline/posts/profile, follow/unfollow a unique user
* You can get simply 'URI:CID' for posts and 'DID' for users when you retrieve (get) them, so you can use them for Linux pipeline or command substitution
* Various output options:
* Only unique identifier such as `URI::CID` or `DID`, for Linux pipeline or command substitution ([See Samples](#samples) )
* Line oriented output with identifier and human friendly text, for listing many records
* Multiline output with full texts of some attributes, for reading details
* JSON output, for preserving record structure derived from atproto library
* Some subcommands such as `get` and `search` allow to output to files per records
### Requirements
* Python 3.12 or later
### Install from github repository
```bash
pip install git+https://github.com/simpleskyclient/ssky.git
```
## Quick Start
Ssky's behavior is specified by subcommand and options like `ssky subcommand [options]`.
### Common options and names
* Common option -D, --delimiter: Delimiter string in output
* Common option -I, --id: Identifier only such as `URI::CID` or `DID`, depending on context
* Common option -T, --text: Text only such as main text in post or description in user profile
* Common option -L, --long: Long output
* Common option -J, --json: JSON output
* Common option -N NUM, --limit NUM: MAX result counts
* Common option -O DIR, --output DIR: Output to files in the specified directory
* Common name "myself": replace with login user DID or handle automatically
### Login bluesky
First or all, you must log in the Bluesky.
```sh
ssky login handle password
```
*Handle* and *password* are formatted like `xxxx.bsky.social` and `xxxx-xxxxx-xxxx-xxxx`, respectively.
Once you have logged in, ssky remembers the login session in local environment (`~/.ssky`).
However, you must log in again when ssky reports session timeout error like "400 Token has been revoked".
You can also set Bluesky handle and password in environment variable `SSKY_USER`, separated by ':' like `handle:password`.
```sh
export SSKY_USER=user.bsky.social:xxxx-xxxxx-xxxx-xxxx
```
The environment variable overrides command line arguments, so you will login by the user alpha in the following example.
```sh
SSKY_USER=alpha:password1 ssky login bravo password2
```
### Get posts
Get subcommand retrieves your timeline, another author's feed by handle or `DID`, and a post by `URI` or `URI::CID`.
```sh
ssky get # Get your timeline
ssky get handle # Get other author's feed by handle, such as user.bsky.social
ssky get did:... # Get other author's feed by DID
ssky get at://... # Get a post specified by URI
```
### Get profile
Profile subcommand retrieves the user profile from handle or display name.
```sh
ssky profile user.bsky.social
ssky profile 'Display Name'
```
### Post
Post subcommand sends a post. You can give the message by command line argument or the standard input. Tags, link cards, mentions, quotations, reply-to and attached images are available.
```sh
ssky post Hello # Post from command line text
echo Hello | ssky post # Post from /dev/stdin
ssky post 'Hello, #bluesky @atproto.com https://bsky.app/' # Post with tags, mentions, and embed link card
ssky post 'Hello, bluesky!' --image dir1/hello1.png --image dir2/hello2.png # Post with images
ssky post 'Hello, bluesky!' --quote at://... # Quote the post
ssky post 'Hello, bluesky!' --reply-to at://... # Reply to the post
ssky post Hello --dry # Dry run
```
### Search posts
Search subcommand searches posts.
```sh
ssky search foo # Search posts including 'foo'
ssky search foo --author handle # Search posts including 'foo' by the specified author
ssky search foo --since 20240101 --until 20241231 # Search posts including 'foo' in the specified period
```
### Delete post
Delete subcommand deletes a post.
```sh
ssky delete at://... # Delete the post
```
### Repost to post
Repost subcommand reposts the post.
```sh
ssky repost at://... # Repost the post
```
### Unrepost to post
Repost subcommand deletes the repost to a post.
```sh
ssky unrepost at://... # Delete your repost to the specified post
```
### Search users
User subcommand searches users.
```sh
ssky user foo # Search users including 'foo' in handle name and description
```
### Follow user
Follow subcommand follows a user.
```sh
ssky follow handle # Follow the user
ssky follow did:.. # Follow the user
```
### Unfollow user
Unfollow subcommand deletes the follow to the user.
```sh
ssky unfollow handle # Unfollow the user
ssky unfollow did:.. # Unfollow the user
```
## Samples
### Search keyword 'bluesky' in your posts
```sh
ssky search bluesky --author myself
```
### Save your last post in the directory './log'
```sh
ssky post 'My very important posted message'
ssky get myself --limit 1 --text --output ./log
```
### Reply to the last post by myself
```sh
ssky post 'Reply!' --reply-to $(ssky get myself --limit 1 --id)
```
## License
[MIT License](LICENSE)
## Author
[SimpleSkyClient Project](https://github.com/simpleskyclient)
Raw data
{
"_id": null,
"home_page": "https://github.com/simpleskyclient/ssky",
"name": "ssky",
"maintainer": null,
"docs_url": null,
"requires_python": "<3.14,>=3.12",
"maintainer_email": null,
"keywords": "bluesky, client",
"author": "SimpleSkyClient Project",
"author_email": "simpleskypclient@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/20/95/ef0cffdc836d30a7cc709cb76589dcbd7448a0fa03a7327840e3b7371edf/ssky-0.1.0.tar.gz",
"platform": null,
"description": "# ssky - Simple Bluesky client\n\n## Introduction\n\nSsky is a simple Bluesky client, providing some specific features.\n\n* Simple but Linux shell friendly user interface\n * You can give `URI` or `URI::CID` to retrieve (get), quote, reply-to, repost/unrepost and delete a unique post\n * You can give `DID` or `handle` to retrieve timeline/posts/profile, follow/unfollow a unique user\n * You can get simply 'URI:CID' for posts and 'DID' for users when you retrieve (get) them, so you can use them for Linux pipeline or command substitution\n * Various output options:\n * Only unique identifier such as `URI::CID` or `DID`, for Linux pipeline or command substitution ([See Samples](#samples) )\n * Line oriented output with identifier and human friendly text, for listing many records\n * Multiline output with full texts of some attributes, for reading details\n * JSON output, for preserving record structure derived from atproto library\n * Some subcommands such as `get` and `search` allow to output to files per records\n\n### Requirements\n\n* Python 3.12 or later\n\n### Install from github repository\n\n```bash\npip install git+https://github.com/simpleskyclient/ssky.git\n```\n\n## Quick Start\n\nSsky's behavior is specified by subcommand and options like `ssky subcommand [options]`.\n\n### Common options and names\n\n* Common option -D, --delimiter: Delimiter string in output\n* Common option -I, --id: Identifier only such as `URI::CID` or `DID`, depending on context\n* Common option -T, --text: Text only such as main text in post or description in user profile\n* Common option -L, --long: Long output\n* Common option -J, --json: JSON output\n* Common option -N NUM, --limit NUM: MAX result counts\n* Common option -O DIR, --output DIR: Output to files in the specified directory\n* Common name \"myself\": replace with login user DID or handle automatically\n\n### Login bluesky\n\nFirst or all, you must log in the Bluesky.\n\n```sh\nssky login handle password\n```\n\n*Handle* and *password* are formatted like `xxxx.bsky.social` and `xxxx-xxxxx-xxxx-xxxx`, respectively.\n\nOnce you have logged in, ssky remembers the login session in local environment (`~/.ssky`).\nHowever, you must log in again when ssky reports session timeout error like \"400 Token has been revoked\".\n\nYou can also set Bluesky handle and password in environment variable `SSKY_USER`, separated by ':' like `handle:password`.\n\n```sh\nexport SSKY_USER=user.bsky.social:xxxx-xxxxx-xxxx-xxxx\n```\n\nThe environment variable overrides command line arguments, so you will login by the user alpha in the following example.\n\n```sh\nSSKY_USER=alpha:password1 ssky login bravo password2\n```\n\n### Get posts\n\nGet subcommand retrieves your timeline, another author's feed by handle or `DID`, and a post by `URI` or `URI::CID`.\n\n```sh\nssky get # Get your timeline\nssky get handle # Get other author's feed by handle, such as user.bsky.social\nssky get did:... # Get other author's feed by DID\nssky get at://... # Get a post specified by URI\n```\n\n### Get profile\n\nProfile subcommand retrieves the user profile from handle or display name.\n\n```sh\nssky profile user.bsky.social\nssky profile 'Display Name'\n```\n\n### Post\n\nPost subcommand sends a post. You can give the message by command line argument or the standard input. Tags, link cards, mentions, quotations, reply-to and attached images are available.\n\n```sh\nssky post Hello # Post from command line text\necho Hello | ssky post # Post from /dev/stdin\nssky post 'Hello, #bluesky @atproto.com https://bsky.app/' # Post with tags, mentions, and embed link card\nssky post 'Hello, bluesky!' --image dir1/hello1.png --image dir2/hello2.png # Post with images\nssky post 'Hello, bluesky!' --quote at://... # Quote the post\nssky post 'Hello, bluesky!' --reply-to at://... # Reply to the post\n\nssky post Hello --dry # Dry run\n```\n\n### Search posts\n\nSearch subcommand searches posts.\n\n```sh\nssky search foo # Search posts including 'foo'\nssky search foo --author handle # Search posts including 'foo' by the specified author\nssky search foo --since 20240101 --until 20241231 # Search posts including 'foo' in the specified period\n```\n\n### Delete post\n\nDelete subcommand deletes a post.\n\n```sh\nssky delete at://... # Delete the post\n```\n\n### Repost to post\n\nRepost subcommand reposts the post.\n\n```sh\nssky repost at://... # Repost the post\n```\n\n### Unrepost to post\n\nRepost subcommand deletes the repost to a post.\n\n```sh\nssky unrepost at://... # Delete your repost to the specified post\n```\n\n### Search users\n\nUser subcommand searches users.\n\n```sh\nssky user foo # Search users including 'foo' in handle name and description\n```\n\n### Follow user\n\nFollow subcommand follows a user.\n\n```sh\nssky follow handle # Follow the user\nssky follow did:.. # Follow the user\n```\n\n### Unfollow user\n\nUnfollow subcommand deletes the follow to the user.\n\n```sh\nssky unfollow handle # Unfollow the user\nssky unfollow did:.. # Unfollow the user\n```\n\n## Samples\n\n### Search keyword 'bluesky' in your posts\n\n```sh\nssky search bluesky --author myself\n```\n\n### Save your last post in the directory './log'\n\n```sh\nssky post 'My very important posted message'\nssky get myself --limit 1 --text --output ./log\n```\n\n### Reply to the last post by myself\n\n```sh\nssky post 'Reply!' --reply-to $(ssky get myself --limit 1 --id)\n```\n\n## License\n\n[MIT License](LICENSE)\n\n## Author\n\n[SimpleSkyClient Project](https://github.com/simpleskyclient)\n",
"bugtrack_url": null,
"license": "LICENSE",
"summary": "Simple bluesky client",
"version": "0.1.0",
"project_urls": {
"Homepage": "https://github.com/simpleskyclient/ssky",
"Repository": "https://github.com/simpleskyclient/ssky"
},
"split_keywords": [
"bluesky",
" client"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "33fe6a886a62ce8a5776ca683e6d1614b4cb57a9b7eb5dedc10cfbf9de49f59c",
"md5": "24e4d1d8d7f322007a5644582ec2bc74",
"sha256": "08e686e4086916f99497e872ab0b31826a29cf5f6ff42d933063313aed4cd8fa"
},
"downloads": -1,
"filename": "ssky-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "24e4d1d8d7f322007a5644582ec2bc74",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<3.14,>=3.12",
"size": 19218,
"upload_time": "2025-01-20T02:49:10",
"upload_time_iso_8601": "2025-01-20T02:49:10.481196Z",
"url": "https://files.pythonhosted.org/packages/33/fe/6a886a62ce8a5776ca683e6d1614b4cb57a9b7eb5dedc10cfbf9de49f59c/ssky-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2095ef0cffdc836d30a7cc709cb76589dcbd7448a0fa03a7327840e3b7371edf",
"md5": "fa3144ac932f42e7f8271908cda4c6c9",
"sha256": "da44ace07bd4d799c4086b11fdd26b7dcd6aaee9d297b432cf0ca06a533c8be1"
},
"downloads": -1,
"filename": "ssky-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "fa3144ac932f42e7f8271908cda4c6c9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<3.14,>=3.12",
"size": 14646,
"upload_time": "2025-01-20T02:49:12",
"upload_time_iso_8601": "2025-01-20T02:49:12.877716Z",
"url": "https://files.pythonhosted.org/packages/20/95/ef0cffdc836d30a7cc709cb76589dcbd7448a0fa03a7327840e3b7371edf/ssky-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-20 02:49:12",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "simpleskyclient",
"github_project": "ssky",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "ssky"
}