bluemastodon 0.9.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bluemastodon-0.9.3/LICENSE +21 -0
- bluemastodon-0.9.3/PKG-INFO +358 -0
- bluemastodon-0.9.3/README.md +339 -0
- bluemastodon-0.9.3/pyproject.toml +60 -0
- bluemastodon-0.9.3/src/bluemastodon/__init__.py +132 -0
- bluemastodon-0.9.3/src/bluemastodon/__main__.py +8 -0
- bluemastodon-0.9.3/src/bluemastodon/bluesky.py +237 -0
- bluemastodon-0.9.3/src/bluemastodon/config.py +105 -0
- bluemastodon-0.9.3/src/bluemastodon/mastodon.py +594 -0
- bluemastodon-0.9.3/src/bluemastodon/models.py +99 -0
- bluemastodon-0.9.3/src/bluemastodon/sync.py +225 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Travis Cole
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: bluemastodon
|
|
3
|
+
Version: 0.9.3
|
|
4
|
+
Summary: A tool to synchronize posts from Bluesky to Mastodon
|
|
5
|
+
Author: Travis Cole
|
|
6
|
+
Author-email: kelp@plek.org
|
|
7
|
+
Requires-Python: >=3.10,<3.14
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Requires-Dist: atproto (>=0.0.59)
|
|
13
|
+
Requires-Dist: loguru (>=0.7.2)
|
|
14
|
+
Requires-Dist: mastodon-py[blurhash] (>=1.8.1)
|
|
15
|
+
Requires-Dist: pydantic (>=2.6.1)
|
|
16
|
+
Requires-Dist: python-dotenv (>=1.0.0)
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# BlueMastodon
|
|
20
|
+
|
|
21
|
+
A Python application to automatically cross-post manual Bluesky posts to Mastodon.
|
|
22
|
+
|
|
23
|
+
*Formerly known as bluemastodon*
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+

|
|
27
|
+

|
|
28
|
+

|
|
29
|
+

|
|
30
|
+
|
|
31
|
+
## Overview
|
|
32
|
+
|
|
33
|
+
BlueMastodon monitors your Bluesky account for new posts and automatically
|
|
34
|
+
cross-posts them to your Mastodon account. It's designed to be run as a
|
|
35
|
+
scheduled job via GitHub Actions or any other scheduler.
|
|
36
|
+
|
|
37
|
+
This tool specifically handles synchronizing manual posts from Bluesky to
|
|
38
|
+
Mastodon. Blog post publishing to social platforms can be managed by a
|
|
39
|
+
separate tool.
|
|
40
|
+
|
|
41
|
+
## Features
|
|
42
|
+
|
|
43
|
+
- 🔄 **Automatic Synchronization**: Fetches recent Bluesky posts and
|
|
44
|
+
cross-posts to Mastodon
|
|
45
|
+
- 🖼️ **Media Support**: Transfers images and attachments between platforms
|
|
46
|
+
- 🔗 **Link Handling**: Preserves external links in your posts
|
|
47
|
+
- 🧠 **Smart Synchronization**: Keeps track of synced posts to avoid duplicates
|
|
48
|
+
- 📝 **Format Preservation**: Maintains post formatting during cross-posting
|
|
49
|
+
- 🚨 **Error Handling**: Robust error handling and logging
|
|
50
|
+
- 🔒 **Secure**: Handles API credentials securely
|
|
51
|
+
- 🤖 **GitHub Action Ready**: Easily deployable as a GitHub Actions workflow
|
|
52
|
+
|
|
53
|
+
## Setup
|
|
54
|
+
|
|
55
|
+
### Prerequisites
|
|
56
|
+
|
|
57
|
+
- Python 3.10 or higher (tested on 3.10, 3.11, 3.12, 3.13)
|
|
58
|
+
- A Bluesky account
|
|
59
|
+
- A Mastodon account with API access
|
|
60
|
+
|
|
61
|
+
### Installation
|
|
62
|
+
|
|
63
|
+
#### Using pip
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install bluemastodon
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### Using Poetry
|
|
70
|
+
|
|
71
|
+
1. Clone the repository:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
git clone https://github.com/kelp/bluemastodon.git
|
|
75
|
+
cd bluemastodon
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
2. Install with Poetry:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
poetry install
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Configuration
|
|
85
|
+
|
|
86
|
+
Create a `.env` file with your credentials:
|
|
87
|
+
|
|
88
|
+
```env
|
|
89
|
+
# Required credentials
|
|
90
|
+
BLUESKY_USERNAME=your_bluesky_username
|
|
91
|
+
BLUESKY_PASSWORD=your_bluesky_password
|
|
92
|
+
MASTODON_INSTANCE_URL=https://your.mastodon.instance
|
|
93
|
+
MASTODON_ACCESS_TOKEN=your_mastodon_access_token
|
|
94
|
+
|
|
95
|
+
# Optional settings with defaults
|
|
96
|
+
LOOKBACK_HOURS=24 # How far back to look for posts
|
|
97
|
+
SYNC_INTERVAL_MINUTES=60 # Frequency of synchronization
|
|
98
|
+
MAX_POSTS_PER_RUN=5 # Maximum posts to sync in one run
|
|
99
|
+
INCLUDE_MEDIA=true # Include media attachments
|
|
100
|
+
INCLUDE_LINKS=true # Include post links
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### Obtaining API Credentials
|
|
104
|
+
|
|
105
|
+
##### Bluesky
|
|
106
|
+
|
|
107
|
+
For Bluesky, you'll need your username and application password.
|
|
108
|
+
|
|
109
|
+
##### Mastodon
|
|
110
|
+
|
|
111
|
+
1. Log in to your Mastodon instance
|
|
112
|
+
2. Go to Preferences > Development > New Application
|
|
113
|
+
3. Give your app a name and select the following permissions:
|
|
114
|
+
- `read:accounts`
|
|
115
|
+
- `read:statuses`
|
|
116
|
+
- `write:media`
|
|
117
|
+
- `write:statuses`
|
|
118
|
+
4. Save and copy the "Access token"
|
|
119
|
+
|
|
120
|
+
## Usage
|
|
121
|
+
|
|
122
|
+
### Command Line
|
|
123
|
+
|
|
124
|
+
Run the sync manually:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# If installed with pip
|
|
128
|
+
bluemastodon
|
|
129
|
+
|
|
130
|
+
# If using Poetry
|
|
131
|
+
poetry run python -m social_sync
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### Options
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
-c, --config Path to custom config file (.env format)
|
|
138
|
+
-s, --state Path to custom state file (JSON format)
|
|
139
|
+
-d, --debug Enable debug logging
|
|
140
|
+
--dry-run Simulate syncing without posting
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Example Commands
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Run with debug logging
|
|
147
|
+
bluemastodon --debug
|
|
148
|
+
|
|
149
|
+
# Dry run (no actual posts)
|
|
150
|
+
bluemastodon --dry-run
|
|
151
|
+
|
|
152
|
+
# Use custom config file
|
|
153
|
+
bluemastodon --config /path/to/custom.env
|
|
154
|
+
|
|
155
|
+
# Specify state file location
|
|
156
|
+
bluemastodon --state /path/to/state.json
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Scheduled Sync with GitHub Actions
|
|
160
|
+
|
|
161
|
+
#### Setting Up Securely with GitHub Secrets
|
|
162
|
+
|
|
163
|
+
BlueMastodon is designed to work with GitHub Actions in a secure way, using
|
|
164
|
+
GitHub's encrypted secrets feature to store sensitive credentials:
|
|
165
|
+
|
|
166
|
+
1. Fork this repository or copy the workflow files to your own repository
|
|
167
|
+
2. In your GitHub repository, go to "Settings" > "Secrets and variables" >
|
|
168
|
+
"Actions"
|
|
169
|
+
3. Add the following repository secrets (these are encrypted and secure):
|
|
170
|
+
- `BLUESKY_USERNAME`: Your Bluesky username
|
|
171
|
+
- `BLUESKY_PASSWORD`: Your Bluesky application password
|
|
172
|
+
- `MASTODON_INSTANCE_URL`: Your Mastodon instance URL
|
|
173
|
+
- `MASTODON_ACCESS_TOKEN`: Your Mastodon API access token
|
|
174
|
+
|
|
175
|
+
For detailed instructions on obtaining and setting up these secrets, see the
|
|
176
|
+
[GitHub Secrets Setup Guide](docs/setup-github-secrets.md).
|
|
177
|
+
|
|
178
|
+
> **SECURITY WARNING**: Never commit your actual credentials to the repository!
|
|
179
|
+
> Always use GitHub Secrets for sensitive information.
|
|
180
|
+
|
|
181
|
+
#### Optional Configuration Variables
|
|
182
|
+
|
|
183
|
+
You can also add these as repository variables (not secrets, as they're not
|
|
184
|
+
sensitive):
|
|
185
|
+
|
|
186
|
+
1. Go to "Settings" > "Secrets and variables" > "Actions" > "Variables" tab
|
|
187
|
+
2. Configure any of the following:
|
|
188
|
+
- `LOOKBACK_HOURS`: How far back to look for posts (default: 24)
|
|
189
|
+
- `SYNC_INTERVAL_MINUTES`: How often to sync (default: 60)
|
|
190
|
+
- `MAX_POSTS_PER_RUN`: Maximum posts to sync (default: 5)
|
|
191
|
+
- `INCLUDE_MEDIA`: Whether to include media (default: true)
|
|
192
|
+
- `INCLUDE_LINKS`: Whether to include links (default: true)
|
|
193
|
+
|
|
194
|
+
#### Running the Workflow
|
|
195
|
+
|
|
196
|
+
1. Enable the workflow in your GitHub repository (go to "Actions" tab)
|
|
197
|
+
2. The sync will run automatically according to the schedule (hourly by default)
|
|
198
|
+
3. You can also trigger it manually from the Actions tab by clicking "Run
|
|
199
|
+
workflow"
|
|
200
|
+
4. For manual runs, you can enable debug mode or dry-run mode using the provided
|
|
201
|
+
options
|
|
202
|
+
|
|
203
|
+
#### How Duplicate Posts Are Prevented
|
|
204
|
+
|
|
205
|
+
BlueMastodon uses a robust state tracking system to prevent duplicate posts:
|
|
206
|
+
|
|
207
|
+
1. **State File**: Each run maintains a JSON file with IDs of previously synced
|
|
208
|
+
posts
|
|
209
|
+
2. **GitHub Actions Cache**: The state file is persisted between runs using
|
|
210
|
+
GitHub's cache
|
|
211
|
+
3. **Lookback Window**: The tool only examines posts from the last 6 hours
|
|
212
|
+
(configurable)
|
|
213
|
+
4. **Deduplication Logic**: Posts with IDs already in the state file are
|
|
214
|
+
automatically skipped
|
|
215
|
+
|
|
216
|
+
This system ensures:
|
|
217
|
+
- Each post is only synced once, even across multiple workflow runs
|
|
218
|
+
- If a workflow run is missed, posts are still captured in the next run
|
|
219
|
+
- Even if the cache is lost, only posts within the lookback window might be
|
|
220
|
+
duplicated
|
|
221
|
+
|
|
222
|
+
For advanced cache management options (including how to clear the cache), see
|
|
223
|
+
[Managing GitHub Actions Cache](docs/managing-cache.md).
|
|
224
|
+
|
|
225
|
+
## Development
|
|
226
|
+
|
|
227
|
+
### Version Information
|
|
228
|
+
|
|
229
|
+
BlueMastodon follows [Semantic Versioning](https://semver.org/) and is currently
|
|
230
|
+
at version 0.9.3 (beta). For more information about our versioning system
|
|
231
|
+
and release process, see [Versioning Guidelines](docs/versioning.md).
|
|
232
|
+
|
|
233
|
+
### Setup Development Environment
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Clone the repository
|
|
237
|
+
git clone https://github.com/kelp/bluemastodon.git
|
|
238
|
+
cd bluemastodon
|
|
239
|
+
|
|
240
|
+
# Run the setup script (installs dependencies and pre-commit hooks)
|
|
241
|
+
./scripts/setup-dev.sh
|
|
242
|
+
|
|
243
|
+
# Or manually:
|
|
244
|
+
# Install dependencies
|
|
245
|
+
poetry install
|
|
246
|
+
|
|
247
|
+
# Install pre-commit hooks
|
|
248
|
+
pre-commit install
|
|
249
|
+
pre-commit install --hook-type pre-push
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
#### Pre-commit Hooks
|
|
253
|
+
|
|
254
|
+
This project uses pre-commit hooks to ensure code quality. The hooks run:
|
|
255
|
+
|
|
256
|
+
- Code formatting (Black, isort)
|
|
257
|
+
- Linting (Flake8, pylint)
|
|
258
|
+
- Type checking (Mypy)
|
|
259
|
+
- Security analysis (Bandit)
|
|
260
|
+
- Tests with minimum coverage requirements (pytest)
|
|
261
|
+
|
|
262
|
+
Pre-commit hooks run automatically on commit. Pre-push hooks run more
|
|
263
|
+
comprehensive checks before pushing to the remote repository.
|
|
264
|
+
|
|
265
|
+
### Testing
|
|
266
|
+
|
|
267
|
+
Run tests with coverage:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
# Run all tests
|
|
271
|
+
make test
|
|
272
|
+
|
|
273
|
+
# Run with coverage report
|
|
274
|
+
make test-cov
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Linting and Formatting
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# Format code
|
|
281
|
+
make format
|
|
282
|
+
|
|
283
|
+
# Run linting
|
|
284
|
+
make lint
|
|
285
|
+
|
|
286
|
+
# Run type checking
|
|
287
|
+
make type-check
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Building and Publishing
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# Build package
|
|
294
|
+
make build
|
|
295
|
+
|
|
296
|
+
# Create a release
|
|
297
|
+
make release
|
|
298
|
+
|
|
299
|
+
# Publish to PyPI (requires credentials)
|
|
300
|
+
make publish
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## Troubleshooting
|
|
304
|
+
|
|
305
|
+
### Common Issues
|
|
306
|
+
|
|
307
|
+
1. **Authentication Errors**:
|
|
308
|
+
- Verify your credentials in the `.env` file
|
|
309
|
+
- Ensure your Mastodon token has the correct permissions
|
|
310
|
+
|
|
311
|
+
2. **No Posts Being Synced**:
|
|
312
|
+
- Check the `LOOKBACK_HOURS` setting
|
|
313
|
+
- Verify that you have recent posts on Bluesky
|
|
314
|
+
- Run with `--debug` for detailed logging
|
|
315
|
+
|
|
316
|
+
3. **Media Not Transferring**:
|
|
317
|
+
- Ensure `INCLUDE_MEDIA=true` in your configuration
|
|
318
|
+
- Some media types might not be supported by both platforms
|
|
319
|
+
|
|
320
|
+
4. **GitHub Actions Not Running**:
|
|
321
|
+
- Check if the workflow is enabled
|
|
322
|
+
- Verify all required secrets are set
|
|
323
|
+
- Check the workflow logs for errors
|
|
324
|
+
|
|
325
|
+
5. **Security Concerns**:
|
|
326
|
+
- Never commit `.env` files with real credentials to your repository
|
|
327
|
+
- Always use GitHub Secrets for sensitive information
|
|
328
|
+
- Regularly rotate your API tokens for better security
|
|
329
|
+
- If you suspect your tokens were compromised, regenerate them immediately
|
|
330
|
+
|
|
331
|
+
6. **Cache Issues**:
|
|
332
|
+
- If you experience duplicate posts, the GitHub Actions cache may have been
|
|
333
|
+
lost
|
|
334
|
+
- Cache can expire after 7 days of non-use or during GitHub maintenance
|
|
335
|
+
- To debug cache issues, check workflow logs for "Cache restored from key:
|
|
336
|
+
sync-state"
|
|
337
|
+
- For instructions on how to view, clear, or reset the cache, see
|
|
338
|
+
[Managing GitHub Actions Cache](docs/managing-cache.md)
|
|
339
|
+
|
|
340
|
+
## License
|
|
341
|
+
|
|
342
|
+
MIT
|
|
343
|
+
|
|
344
|
+
## Contributing
|
|
345
|
+
|
|
346
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
347
|
+
|
|
348
|
+
1. Fork the repository
|
|
349
|
+
2. Create a feature branch: `git checkout -b feature-name`
|
|
350
|
+
3. Commit your changes: `git commit -am 'Add feature'`
|
|
351
|
+
4. Push to the branch: `git push origin feature-name`
|
|
352
|
+
5. Submit a pull request
|
|
353
|
+
|
|
354
|
+
## Acknowledgements
|
|
355
|
+
|
|
356
|
+
- [atproto](https://atproto.blue/en/latest/) for Bluesky API access
|
|
357
|
+
- [Mastodon.py](https://mastodonpy.readthedocs.io/) for Mastodon API access
|
|
358
|
+
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# BlueMastodon
|
|
2
|
+
|
|
3
|
+
A Python application to automatically cross-post manual Bluesky posts to Mastodon.
|
|
4
|
+
|
|
5
|
+
*Formerly known as bluemastodon*
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
BlueMastodon monitors your Bluesky account for new posts and automatically
|
|
16
|
+
cross-posts them to your Mastodon account. It's designed to be run as a
|
|
17
|
+
scheduled job via GitHub Actions or any other scheduler.
|
|
18
|
+
|
|
19
|
+
This tool specifically handles synchronizing manual posts from Bluesky to
|
|
20
|
+
Mastodon. Blog post publishing to social platforms can be managed by a
|
|
21
|
+
separate tool.
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- 🔄 **Automatic Synchronization**: Fetches recent Bluesky posts and
|
|
26
|
+
cross-posts to Mastodon
|
|
27
|
+
- 🖼️ **Media Support**: Transfers images and attachments between platforms
|
|
28
|
+
- 🔗 **Link Handling**: Preserves external links in your posts
|
|
29
|
+
- 🧠 **Smart Synchronization**: Keeps track of synced posts to avoid duplicates
|
|
30
|
+
- 📝 **Format Preservation**: Maintains post formatting during cross-posting
|
|
31
|
+
- 🚨 **Error Handling**: Robust error handling and logging
|
|
32
|
+
- 🔒 **Secure**: Handles API credentials securely
|
|
33
|
+
- 🤖 **GitHub Action Ready**: Easily deployable as a GitHub Actions workflow
|
|
34
|
+
|
|
35
|
+
## Setup
|
|
36
|
+
|
|
37
|
+
### Prerequisites
|
|
38
|
+
|
|
39
|
+
- Python 3.10 or higher (tested on 3.10, 3.11, 3.12, 3.13)
|
|
40
|
+
- A Bluesky account
|
|
41
|
+
- A Mastodon account with API access
|
|
42
|
+
|
|
43
|
+
### Installation
|
|
44
|
+
|
|
45
|
+
#### Using pip
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install bluemastodon
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### Using Poetry
|
|
52
|
+
|
|
53
|
+
1. Clone the repository:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
git clone https://github.com/kelp/bluemastodon.git
|
|
57
|
+
cd bluemastodon
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
2. Install with Poetry:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
poetry install
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Configuration
|
|
67
|
+
|
|
68
|
+
Create a `.env` file with your credentials:
|
|
69
|
+
|
|
70
|
+
```env
|
|
71
|
+
# Required credentials
|
|
72
|
+
BLUESKY_USERNAME=your_bluesky_username
|
|
73
|
+
BLUESKY_PASSWORD=your_bluesky_password
|
|
74
|
+
MASTODON_INSTANCE_URL=https://your.mastodon.instance
|
|
75
|
+
MASTODON_ACCESS_TOKEN=your_mastodon_access_token
|
|
76
|
+
|
|
77
|
+
# Optional settings with defaults
|
|
78
|
+
LOOKBACK_HOURS=24 # How far back to look for posts
|
|
79
|
+
SYNC_INTERVAL_MINUTES=60 # Frequency of synchronization
|
|
80
|
+
MAX_POSTS_PER_RUN=5 # Maximum posts to sync in one run
|
|
81
|
+
INCLUDE_MEDIA=true # Include media attachments
|
|
82
|
+
INCLUDE_LINKS=true # Include post links
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Obtaining API Credentials
|
|
86
|
+
|
|
87
|
+
##### Bluesky
|
|
88
|
+
|
|
89
|
+
For Bluesky, you'll need your username and application password.
|
|
90
|
+
|
|
91
|
+
##### Mastodon
|
|
92
|
+
|
|
93
|
+
1. Log in to your Mastodon instance
|
|
94
|
+
2. Go to Preferences > Development > New Application
|
|
95
|
+
3. Give your app a name and select the following permissions:
|
|
96
|
+
- `read:accounts`
|
|
97
|
+
- `read:statuses`
|
|
98
|
+
- `write:media`
|
|
99
|
+
- `write:statuses`
|
|
100
|
+
4. Save and copy the "Access token"
|
|
101
|
+
|
|
102
|
+
## Usage
|
|
103
|
+
|
|
104
|
+
### Command Line
|
|
105
|
+
|
|
106
|
+
Run the sync manually:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# If installed with pip
|
|
110
|
+
bluemastodon
|
|
111
|
+
|
|
112
|
+
# If using Poetry
|
|
113
|
+
poetry run python -m social_sync
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### Options
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
-c, --config Path to custom config file (.env format)
|
|
120
|
+
-s, --state Path to custom state file (JSON format)
|
|
121
|
+
-d, --debug Enable debug logging
|
|
122
|
+
--dry-run Simulate syncing without posting
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### Example Commands
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Run with debug logging
|
|
129
|
+
bluemastodon --debug
|
|
130
|
+
|
|
131
|
+
# Dry run (no actual posts)
|
|
132
|
+
bluemastodon --dry-run
|
|
133
|
+
|
|
134
|
+
# Use custom config file
|
|
135
|
+
bluemastodon --config /path/to/custom.env
|
|
136
|
+
|
|
137
|
+
# Specify state file location
|
|
138
|
+
bluemastodon --state /path/to/state.json
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Scheduled Sync with GitHub Actions
|
|
142
|
+
|
|
143
|
+
#### Setting Up Securely with GitHub Secrets
|
|
144
|
+
|
|
145
|
+
BlueMastodon is designed to work with GitHub Actions in a secure way, using
|
|
146
|
+
GitHub's encrypted secrets feature to store sensitive credentials:
|
|
147
|
+
|
|
148
|
+
1. Fork this repository or copy the workflow files to your own repository
|
|
149
|
+
2. In your GitHub repository, go to "Settings" > "Secrets and variables" >
|
|
150
|
+
"Actions"
|
|
151
|
+
3. Add the following repository secrets (these are encrypted and secure):
|
|
152
|
+
- `BLUESKY_USERNAME`: Your Bluesky username
|
|
153
|
+
- `BLUESKY_PASSWORD`: Your Bluesky application password
|
|
154
|
+
- `MASTODON_INSTANCE_URL`: Your Mastodon instance URL
|
|
155
|
+
- `MASTODON_ACCESS_TOKEN`: Your Mastodon API access token
|
|
156
|
+
|
|
157
|
+
For detailed instructions on obtaining and setting up these secrets, see the
|
|
158
|
+
[GitHub Secrets Setup Guide](docs/setup-github-secrets.md).
|
|
159
|
+
|
|
160
|
+
> **SECURITY WARNING**: Never commit your actual credentials to the repository!
|
|
161
|
+
> Always use GitHub Secrets for sensitive information.
|
|
162
|
+
|
|
163
|
+
#### Optional Configuration Variables
|
|
164
|
+
|
|
165
|
+
You can also add these as repository variables (not secrets, as they're not
|
|
166
|
+
sensitive):
|
|
167
|
+
|
|
168
|
+
1. Go to "Settings" > "Secrets and variables" > "Actions" > "Variables" tab
|
|
169
|
+
2. Configure any of the following:
|
|
170
|
+
- `LOOKBACK_HOURS`: How far back to look for posts (default: 24)
|
|
171
|
+
- `SYNC_INTERVAL_MINUTES`: How often to sync (default: 60)
|
|
172
|
+
- `MAX_POSTS_PER_RUN`: Maximum posts to sync (default: 5)
|
|
173
|
+
- `INCLUDE_MEDIA`: Whether to include media (default: true)
|
|
174
|
+
- `INCLUDE_LINKS`: Whether to include links (default: true)
|
|
175
|
+
|
|
176
|
+
#### Running the Workflow
|
|
177
|
+
|
|
178
|
+
1. Enable the workflow in your GitHub repository (go to "Actions" tab)
|
|
179
|
+
2. The sync will run automatically according to the schedule (hourly by default)
|
|
180
|
+
3. You can also trigger it manually from the Actions tab by clicking "Run
|
|
181
|
+
workflow"
|
|
182
|
+
4. For manual runs, you can enable debug mode or dry-run mode using the provided
|
|
183
|
+
options
|
|
184
|
+
|
|
185
|
+
#### How Duplicate Posts Are Prevented
|
|
186
|
+
|
|
187
|
+
BlueMastodon uses a robust state tracking system to prevent duplicate posts:
|
|
188
|
+
|
|
189
|
+
1. **State File**: Each run maintains a JSON file with IDs of previously synced
|
|
190
|
+
posts
|
|
191
|
+
2. **GitHub Actions Cache**: The state file is persisted between runs using
|
|
192
|
+
GitHub's cache
|
|
193
|
+
3. **Lookback Window**: The tool only examines posts from the last 6 hours
|
|
194
|
+
(configurable)
|
|
195
|
+
4. **Deduplication Logic**: Posts with IDs already in the state file are
|
|
196
|
+
automatically skipped
|
|
197
|
+
|
|
198
|
+
This system ensures:
|
|
199
|
+
- Each post is only synced once, even across multiple workflow runs
|
|
200
|
+
- If a workflow run is missed, posts are still captured in the next run
|
|
201
|
+
- Even if the cache is lost, only posts within the lookback window might be
|
|
202
|
+
duplicated
|
|
203
|
+
|
|
204
|
+
For advanced cache management options (including how to clear the cache), see
|
|
205
|
+
[Managing GitHub Actions Cache](docs/managing-cache.md).
|
|
206
|
+
|
|
207
|
+
## Development
|
|
208
|
+
|
|
209
|
+
### Version Information
|
|
210
|
+
|
|
211
|
+
BlueMastodon follows [Semantic Versioning](https://semver.org/) and is currently
|
|
212
|
+
at version 0.9.3 (beta). For more information about our versioning system
|
|
213
|
+
and release process, see [Versioning Guidelines](docs/versioning.md).
|
|
214
|
+
|
|
215
|
+
### Setup Development Environment
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Clone the repository
|
|
219
|
+
git clone https://github.com/kelp/bluemastodon.git
|
|
220
|
+
cd bluemastodon
|
|
221
|
+
|
|
222
|
+
# Run the setup script (installs dependencies and pre-commit hooks)
|
|
223
|
+
./scripts/setup-dev.sh
|
|
224
|
+
|
|
225
|
+
# Or manually:
|
|
226
|
+
# Install dependencies
|
|
227
|
+
poetry install
|
|
228
|
+
|
|
229
|
+
# Install pre-commit hooks
|
|
230
|
+
pre-commit install
|
|
231
|
+
pre-commit install --hook-type pre-push
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
#### Pre-commit Hooks
|
|
235
|
+
|
|
236
|
+
This project uses pre-commit hooks to ensure code quality. The hooks run:
|
|
237
|
+
|
|
238
|
+
- Code formatting (Black, isort)
|
|
239
|
+
- Linting (Flake8, pylint)
|
|
240
|
+
- Type checking (Mypy)
|
|
241
|
+
- Security analysis (Bandit)
|
|
242
|
+
- Tests with minimum coverage requirements (pytest)
|
|
243
|
+
|
|
244
|
+
Pre-commit hooks run automatically on commit. Pre-push hooks run more
|
|
245
|
+
comprehensive checks before pushing to the remote repository.
|
|
246
|
+
|
|
247
|
+
### Testing
|
|
248
|
+
|
|
249
|
+
Run tests with coverage:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# Run all tests
|
|
253
|
+
make test
|
|
254
|
+
|
|
255
|
+
# Run with coverage report
|
|
256
|
+
make test-cov
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Linting and Formatting
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Format code
|
|
263
|
+
make format
|
|
264
|
+
|
|
265
|
+
# Run linting
|
|
266
|
+
make lint
|
|
267
|
+
|
|
268
|
+
# Run type checking
|
|
269
|
+
make type-check
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Building and Publishing
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
# Build package
|
|
276
|
+
make build
|
|
277
|
+
|
|
278
|
+
# Create a release
|
|
279
|
+
make release
|
|
280
|
+
|
|
281
|
+
# Publish to PyPI (requires credentials)
|
|
282
|
+
make publish
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Troubleshooting
|
|
286
|
+
|
|
287
|
+
### Common Issues
|
|
288
|
+
|
|
289
|
+
1. **Authentication Errors**:
|
|
290
|
+
- Verify your credentials in the `.env` file
|
|
291
|
+
- Ensure your Mastodon token has the correct permissions
|
|
292
|
+
|
|
293
|
+
2. **No Posts Being Synced**:
|
|
294
|
+
- Check the `LOOKBACK_HOURS` setting
|
|
295
|
+
- Verify that you have recent posts on Bluesky
|
|
296
|
+
- Run with `--debug` for detailed logging
|
|
297
|
+
|
|
298
|
+
3. **Media Not Transferring**:
|
|
299
|
+
- Ensure `INCLUDE_MEDIA=true` in your configuration
|
|
300
|
+
- Some media types might not be supported by both platforms
|
|
301
|
+
|
|
302
|
+
4. **GitHub Actions Not Running**:
|
|
303
|
+
- Check if the workflow is enabled
|
|
304
|
+
- Verify all required secrets are set
|
|
305
|
+
- Check the workflow logs for errors
|
|
306
|
+
|
|
307
|
+
5. **Security Concerns**:
|
|
308
|
+
- Never commit `.env` files with real credentials to your repository
|
|
309
|
+
- Always use GitHub Secrets for sensitive information
|
|
310
|
+
- Regularly rotate your API tokens for better security
|
|
311
|
+
- If you suspect your tokens were compromised, regenerate them immediately
|
|
312
|
+
|
|
313
|
+
6. **Cache Issues**:
|
|
314
|
+
- If you experience duplicate posts, the GitHub Actions cache may have been
|
|
315
|
+
lost
|
|
316
|
+
- Cache can expire after 7 days of non-use or during GitHub maintenance
|
|
317
|
+
- To debug cache issues, check workflow logs for "Cache restored from key:
|
|
318
|
+
sync-state"
|
|
319
|
+
- For instructions on how to view, clear, or reset the cache, see
|
|
320
|
+
[Managing GitHub Actions Cache](docs/managing-cache.md)
|
|
321
|
+
|
|
322
|
+
## License
|
|
323
|
+
|
|
324
|
+
MIT
|
|
325
|
+
|
|
326
|
+
## Contributing
|
|
327
|
+
|
|
328
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
329
|
+
|
|
330
|
+
1. Fork the repository
|
|
331
|
+
2. Create a feature branch: `git checkout -b feature-name`
|
|
332
|
+
3. Commit your changes: `git commit -am 'Add feature'`
|
|
333
|
+
4. Push to the branch: `git push origin feature-name`
|
|
334
|
+
5. Submit a pull request
|
|
335
|
+
|
|
336
|
+
## Acknowledgements
|
|
337
|
+
|
|
338
|
+
- [atproto](https://atproto.blue/en/latest/) for Bluesky API access
|
|
339
|
+
- [Mastodon.py](https://mastodonpy.readthedocs.io/) for Mastodon API access
|