stashify 0.1.0__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.
- stashify-0.1.0/LICENSE +21 -0
- stashify-0.1.0/PKG-INFO +653 -0
- stashify-0.1.0/README.md +622 -0
- stashify-0.1.0/pyproject.toml +92 -0
- stashify-0.1.0/setup.cfg +4 -0
- stashify-0.1.0/src/stash/__init__.py +5 -0
- stashify-0.1.0/src/stash/cli/__init__.py +5 -0
- stashify-0.1.0/src/stash/cli/commands/__init__.py +23 -0
- stashify-0.1.0/src/stash/cli/commands/get.py +160 -0
- stashify-0.1.0/src/stash/cli/commands/info.py +45 -0
- stashify-0.1.0/src/stash/cli/commands/init.py +34 -0
- stashify-0.1.0/src/stash/cli/commands/ls.py +41 -0
- stashify-0.1.0/src/stash/cli/commands/provider.py +124 -0
- stashify-0.1.0/src/stash/cli/commands/put.py +185 -0
- stashify-0.1.0/src/stash/cli/commands/rm.py +82 -0
- stashify-0.1.0/src/stash/cli/commands/status.py +47 -0
- stashify-0.1.0/src/stash/cli/commands/verify.py +100 -0
- stashify-0.1.0/src/stash/cli/main.py +43 -0
- stashify-0.1.0/src/stash/cli/output.py +121 -0
- stashify-0.1.0/src/stash/core/__init__.py +53 -0
- stashify-0.1.0/src/stash/core/chunking.py +102 -0
- stashify-0.1.0/src/stash/core/crypto.py +121 -0
- stashify-0.1.0/src/stash/core/exceptions.py +66 -0
- stashify-0.1.0/src/stash/core/http_status.py +19 -0
- stashify-0.1.0/src/stash/core/jobs.py +235 -0
- stashify-0.1.0/src/stash/core/manifest.py +171 -0
- stashify-0.1.0/src/stash/core/metadata.py +130 -0
- stashify-0.1.0/src/stash/core/storage.py +120 -0
- stashify-0.1.0/src/stash/providers/__init__.py +15 -0
- stashify-0.1.0/src/stash/providers/base.py +48 -0
- stashify-0.1.0/src/stash/providers/discord/__init__.py +12 -0
- stashify-0.1.0/src/stash/providers/discord/auth.py +29 -0
- stashify-0.1.0/src/stash/providers/discord/limits.py +34 -0
- stashify-0.1.0/src/stash/providers/discord/provider.py +250 -0
- stashify-0.1.0/src/stash/providers/telegram/__init__.py +11 -0
- stashify-0.1.0/src/stash/providers/telegram/auth.py +15 -0
- stashify-0.1.0/src/stash/providers/telegram/limits.py +21 -0
- stashify-0.1.0/src/stash/providers/telegram/provider.py +286 -0
- stashify-0.1.0/src/stashify.egg-info/PKG-INFO +653 -0
- stashify-0.1.0/src/stashify.egg-info/SOURCES.txt +42 -0
- stashify-0.1.0/src/stashify.egg-info/dependency_links.txt +1 -0
- stashify-0.1.0/src/stashify.egg-info/entry_points.txt +2 -0
- stashify-0.1.0/src/stashify.egg-info/requires.txt +23 -0
- stashify-0.1.0/src/stashify.egg-info/top_level.txt +1 -0
stashify-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sparklee
|
|
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.
|
stashify-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,653 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stashify
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Privacy-focused CLI storage system using third-party platforms as encrypted backends
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: cryptography>=49.0
|
|
10
|
+
Requires-Dist: click>=8.1
|
|
11
|
+
Requires-Dist: pydantic>=2.7
|
|
12
|
+
Requires-Dist: pydantic-settings>=2.3
|
|
13
|
+
Requires-Dist: sqlite-utils>=3.37
|
|
14
|
+
Requires-Dist: tqdm>=4.70.0
|
|
15
|
+
Requires-Dist: structlog>=24.1
|
|
16
|
+
Requires-Dist: httpx>=0.27
|
|
17
|
+
Requires-Dist: pyyaml>=6.0
|
|
18
|
+
Requires-Dist: rich>=13.0
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: pytest>=9.1.1; extra == "dev"
|
|
21
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
22
|
+
Requires-Dist: pytest-cov>=7.1.0; extra == "dev"
|
|
23
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
24
|
+
Requires-Dist: mypy>=2.3.1; extra == "dev"
|
|
25
|
+
Requires-Dist: pre-commit>=3.7; extra == "dev"
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest>=9.1.1; extra == "test"
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "test"
|
|
29
|
+
Requires-Dist: hypothesis>=6.100; extra == "test"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# Stashify
|
|
33
|
+
|
|
34
|
+
<p align="center">
|
|
35
|
+
<strong>Encrypted storage. Your providers. Your keys.</strong>
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
An open-source, privacy-focused storage system that turns third-party platforms into encrypted storage backends.
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
<p align="center">
|
|
43
|
+
<a href="https://github.com/Sparkleeop/Stashify">
|
|
44
|
+
<img src="https://img.shields.io/github/stars/Sparkleeop/Stashify?style=flat-square" alt="GitHub Stars">
|
|
45
|
+
</a>
|
|
46
|
+
<a href="https://github.com/Sparkleeop/Stashify">
|
|
47
|
+
<img src="https://img.shields.io/github/license/Sparkleeop/Stashify?style=flat-square" alt="License">
|
|
48
|
+
</a>
|
|
49
|
+
<img src="https://img.shields.io/badge/Python-3.12+-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python">
|
|
50
|
+
<img src="https://img.shields.io/badge/Status-Early%20Development-ee8695?style=flat-square" alt="Status">
|
|
51
|
+
</p>
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## What is Stashify?
|
|
56
|
+
|
|
57
|
+
**Stashify** is an open-source, provider-agnostic storage system designed around one simple idea:
|
|
58
|
+
|
|
59
|
+
> **Your storage provider shouldn't have to be your storage system.**
|
|
60
|
+
|
|
61
|
+
Stashify lets you use services such as **Telegram and Discord as storage backends**, while encryption and file management remain under your control.
|
|
62
|
+
|
|
63
|
+
Files are encrypted locally, split into chunks, and uploaded as ciphertext. Chunks can be stored on one provider or distributed across multiple providers depending on your configuration.
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
STASHIFY
|
|
67
|
+
│
|
|
68
|
+
Storage Engine
|
|
69
|
+
│
|
|
70
|
+
┌─────────────┴─────────────┐
|
|
71
|
+
│ │
|
|
72
|
+
Encryption Chunking
|
|
73
|
+
│ │
|
|
74
|
+
└─────────────┬─────────────┘
|
|
75
|
+
│
|
|
76
|
+
Storage Router
|
|
77
|
+
│
|
|
78
|
+
┌─────────────┴─────────────┐
|
|
79
|
+
│ │
|
|
80
|
+
Telegram Discord
|
|
81
|
+
│ │
|
|
82
|
+
encrypted chunks encrypted chunks
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Stashify does **not** provide the underlying storage.
|
|
86
|
+
|
|
87
|
+
It provides the abstraction that lets you use storage you already have access to.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Why Stashify?
|
|
92
|
+
|
|
93
|
+
Traditional cloud storage usually means trusting one provider with both your data and your storage.
|
|
94
|
+
|
|
95
|
+
Stashify separates those concepts.
|
|
96
|
+
|
|
97
|
+
| Problem | Stashify |
|
|
98
|
+
| -------------------------- | ------------------------------------- |
|
|
99
|
+
| Vendor lock-in | Provider-agnostic storage abstraction |
|
|
100
|
+
| Provider sees plaintext | Files are encrypted before upload |
|
|
101
|
+
| Large files | Automatic chunking |
|
|
102
|
+
| Provider-specific limits | Provider-aware chunking and routing |
|
|
103
|
+
| Single provider dependency | Multi-provider storage |
|
|
104
|
+
| Interrupted uploads | Resumable operations |
|
|
105
|
+
| Manual file management | Unified CLI/TUI |
|
|
106
|
+
| Provider-specific APIs | One consistent interface |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Features
|
|
111
|
+
|
|
112
|
+
### Client-side encryption
|
|
113
|
+
|
|
114
|
+
Your files are encrypted **before they leave your device**.
|
|
115
|
+
|
|
116
|
+
```text
|
|
117
|
+
YOUR DEVICE
|
|
118
|
+
│
|
|
119
|
+
Plaintext
|
|
120
|
+
│
|
|
121
|
+
▼
|
|
122
|
+
Encryption
|
|
123
|
+
│
|
|
124
|
+
▼
|
|
125
|
+
Chunking
|
|
126
|
+
│
|
|
127
|
+
▼
|
|
128
|
+
Encrypted ciphertext
|
|
129
|
+
│
|
|
130
|
+
┌──────────┴──────────┐
|
|
131
|
+
▼ ▼
|
|
132
|
+
Telegram Discord
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Storage providers should only receive ciphertext.
|
|
136
|
+
|
|
137
|
+
Stashify is designed around:
|
|
138
|
+
|
|
139
|
+
* Client-side encryption
|
|
140
|
+
* Authenticated encryption (AEAD)
|
|
141
|
+
* Per-file cryptographic keys
|
|
142
|
+
* Proper key derivation
|
|
143
|
+
* Cryptographically secure randomness
|
|
144
|
+
* No custom cryptographic primitives
|
|
145
|
+
* Authenticated chunk integrity
|
|
146
|
+
* Local key management
|
|
147
|
+
|
|
148
|
+
Stashify uses established cryptographic libraries rather than implementing cryptography from scratch.
|
|
149
|
+
|
|
150
|
+
> **Security note:** Stashify does not claim that multi-provider storage makes encryption stronger. Confidentiality comes from the cryptographic design and key management. Multi-provider storage primarily provides distribution, redundancy, and provider independence.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
### Chunked storage
|
|
155
|
+
|
|
156
|
+
Large files are automatically split into manageable chunks.
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
movie.mkv
|
|
160
|
+
│
|
|
161
|
+
▼
|
|
162
|
+
encrypted data
|
|
163
|
+
│
|
|
164
|
+
▼
|
|
165
|
+
┌────────┬────────┬────────┬────────┐
|
|
166
|
+
│ chunk0 │ chunk1 │ chunk2 │ chunk3 │
|
|
167
|
+
└────────┴────────┴────────┴────────┘
|
|
168
|
+
│ │ │ │
|
|
169
|
+
▼ ▼ ▼ ▼
|
|
170
|
+
encrypted encrypted encrypted encrypted
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Each chunk is independently tracked and authenticated.
|
|
174
|
+
|
|
175
|
+
The storage engine can account for provider-specific upload limitations without exposing those implementation details to the rest of the application.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### Multi-provider storage
|
|
180
|
+
|
|
181
|
+
Stashify can distribute a file across multiple storage providers.
|
|
182
|
+
|
|
183
|
+
For example:
|
|
184
|
+
|
|
185
|
+
```text
|
|
186
|
+
100 encrypted chunks
|
|
187
|
+
|
|
188
|
+
Telegram:
|
|
189
|
+
0 2 4 6 8 10 12 ...
|
|
190
|
+
|
|
191
|
+
Discord:
|
|
192
|
+
1 3 5 7 9 11 13 ...
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Multiple storage strategies are planned:
|
|
196
|
+
|
|
197
|
+
| Strategy | Description |
|
|
198
|
+
| -------------- | ----------------------------------------------------- |
|
|
199
|
+
| **Single** | Store all chunks on one provider |
|
|
200
|
+
| **Split** | Distribute chunks across multiple providers |
|
|
201
|
+
| **Balanced** | Dynamically distribute chunks based on provider state |
|
|
202
|
+
| **Replicated** | Store copies across multiple providers |
|
|
203
|
+
|
|
204
|
+
This allows Stashify to build storage around the providers available to you instead of forcing you into a single backend.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
### Provider abstraction
|
|
209
|
+
|
|
210
|
+
Providers are implementations of the same storage interface.
|
|
211
|
+
|
|
212
|
+
```text
|
|
213
|
+
Storage Provider
|
|
214
|
+
│
|
|
215
|
+
┌────────────────┼────────────────┐
|
|
216
|
+
│ │ │
|
|
217
|
+
Telegram Discord S3 / B2
|
|
218
|
+
│ │ │
|
|
219
|
+
└────────────────┼────────────────┘
|
|
220
|
+
│
|
|
221
|
+
Storage Engine
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The core engine does not need to know how Telegram or Discord works.
|
|
225
|
+
|
|
226
|
+
This makes it possible to add new providers without rewriting the storage system.
|
|
227
|
+
|
|
228
|
+
Planned providers include:
|
|
229
|
+
|
|
230
|
+
* S3-compatible storage
|
|
231
|
+
* Backblaze B2
|
|
232
|
+
* Google Drive
|
|
233
|
+
* Local filesystem
|
|
234
|
+
* WebDAV
|
|
235
|
+
* Other community-built providers
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
### Asynchronous transfers
|
|
240
|
+
|
|
241
|
+
Stashify is designed around asynchronous I/O.
|
|
242
|
+
|
|
243
|
+
Large uploads can consist of hundreds or thousands of chunks, so operations should run concurrently with bounded workers.
|
|
244
|
+
|
|
245
|
+
```text
|
|
246
|
+
Upload Queue
|
|
247
|
+
│
|
|
248
|
+
┌───────────┼───────────┐
|
|
249
|
+
▼ ▼ ▼
|
|
250
|
+
Worker 1 Worker 2 Worker 3
|
|
251
|
+
│ │ │
|
|
252
|
+
Telegram Discord Telegram
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
The transfer system is designed to support:
|
|
256
|
+
|
|
257
|
+
* Concurrent uploads
|
|
258
|
+
* Concurrent downloads
|
|
259
|
+
* Bounded concurrency
|
|
260
|
+
* Retries
|
|
261
|
+
* Exponential backoff
|
|
262
|
+
* Provider-aware rate limiting
|
|
263
|
+
* Cancellation
|
|
264
|
+
* Progress reporting
|
|
265
|
+
* Failed-job tracking
|
|
266
|
+
* Resumable operations
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
### Resumable uploads
|
|
271
|
+
|
|
272
|
+
Interrupted transfers shouldn't mean starting from zero.
|
|
273
|
+
|
|
274
|
+
```text
|
|
275
|
+
200 chunks
|
|
276
|
+
|
|
277
|
+
chunk 000 ✓
|
|
278
|
+
chunk 001 ✓
|
|
279
|
+
chunk 002 ✓
|
|
280
|
+
...
|
|
281
|
+
chunk 147 ✓
|
|
282
|
+
chunk 148 ✗
|
|
283
|
+
chunk 149 ✗
|
|
284
|
+
...
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Stashify keeps track of individual chunks so completed work can be preserved across interruptions.
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
### Integrity verification
|
|
292
|
+
|
|
293
|
+
Encrypted chunks are authenticated and tracked using local metadata.
|
|
294
|
+
|
|
295
|
+
Stashify is designed to detect:
|
|
296
|
+
|
|
297
|
+
* Missing chunks
|
|
298
|
+
* Corrupted chunks
|
|
299
|
+
* Modified ciphertext
|
|
300
|
+
* Incomplete downloads
|
|
301
|
+
* Invalid manifests
|
|
302
|
+
* Incorrect chunk ordering
|
|
303
|
+
* Failed reconstruction
|
|
304
|
+
|
|
305
|
+
The final reconstructed file can also be verified against file-level integrity information.
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
### Manifest-based storage
|
|
310
|
+
|
|
311
|
+
Every stored file has a manifest describing how it can be reconstructed.
|
|
312
|
+
|
|
313
|
+
Conceptually:
|
|
314
|
+
|
|
315
|
+
```text
|
|
316
|
+
File
|
|
317
|
+
├── ID
|
|
318
|
+
├── Original name
|
|
319
|
+
├── Original size
|
|
320
|
+
├── Chunk size
|
|
321
|
+
├── Chunk count
|
|
322
|
+
├── Encryption metadata
|
|
323
|
+
├── Integrity information
|
|
324
|
+
│
|
|
325
|
+
└── Chunks
|
|
326
|
+
├── 0 → Telegram → remote ID
|
|
327
|
+
├── 1 → Discord → remote ID
|
|
328
|
+
├── 2 → Telegram → remote ID
|
|
329
|
+
└── ...
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Local metadata is stored in SQLite.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
# Terminal UI (planned)
|
|
337
|
+
|
|
338
|
+
Stashify is designed to have a full interactive terminal interface rather than being limited to traditional commands.
|
|
339
|
+
|
|
340
|
+
Run:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
stashify
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
to launch the TUI.
|
|
347
|
+
|
|
348
|
+
The interface is designed around a keyboard-first workflow with:
|
|
349
|
+
|
|
350
|
+
* Local file explorer
|
|
351
|
+
* Remote storage explorer
|
|
352
|
+
* Multi-file selection
|
|
353
|
+
* Upload/download controls
|
|
354
|
+
* Live transfer progress
|
|
355
|
+
* Provider status
|
|
356
|
+
* Transfer queue
|
|
357
|
+
* Provider management
|
|
358
|
+
* Configuration
|
|
359
|
+
* Search
|
|
360
|
+
* Command palette
|
|
361
|
+
* Keyboard shortcuts
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
# CLI
|
|
366
|
+
|
|
367
|
+
Stashify can also be used without the interactive interface.
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
# Initialize
|
|
371
|
+
stashify init
|
|
372
|
+
|
|
373
|
+
# Configure providers
|
|
374
|
+
stashify provider add telegram
|
|
375
|
+
stashify provider add discord
|
|
376
|
+
|
|
377
|
+
# List providers
|
|
378
|
+
stashify provider list
|
|
379
|
+
|
|
380
|
+
# Upload
|
|
381
|
+
stashify put ./movie.mkv
|
|
382
|
+
|
|
383
|
+
# List stored files
|
|
384
|
+
stashify ls
|
|
385
|
+
|
|
386
|
+
# Inspect a file
|
|
387
|
+
stashify info movie.mkv
|
|
388
|
+
|
|
389
|
+
# Download
|
|
390
|
+
stashify get movie.mkv
|
|
391
|
+
|
|
392
|
+
# Delete
|
|
393
|
+
stashify rm movie.mkv
|
|
394
|
+
|
|
395
|
+
# Verify
|
|
396
|
+
stashify verify movie.mkv
|
|
397
|
+
|
|
398
|
+
# Check status
|
|
399
|
+
stashify status
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
The exact command set may evolve during development.
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
# Provider Support
|
|
407
|
+
|
|
408
|
+
| Provider | Status |
|
|
409
|
+
| ---------------- | -------------- |
|
|
410
|
+
| Telegram | Implemented |
|
|
411
|
+
| Discord | Implemented |
|
|
412
|
+
| S3-compatible | Planned |
|
|
413
|
+
| Backblaze B2 | Planned |
|
|
414
|
+
| Google Drive | Planned |
|
|
415
|
+
| Local filesystem | Planned |
|
|
416
|
+
| WebDAV | Planned |
|
|
417
|
+
|
|
418
|
+
Provider availability and capabilities are subject to the APIs, limits, and policies of the respective services.
|
|
419
|
+
|
|
420
|
+
### About "unlimited storage"
|
|
421
|
+
|
|
422
|
+
Stashify does **not** provide unlimited storage.
|
|
423
|
+
|
|
424
|
+
It does not bypass provider limits or guarantee unlimited capacity.
|
|
425
|
+
|
|
426
|
+
Actual storage capacity, file-size limits, rate limits, retention policies, and availability depend on the underlying provider.
|
|
427
|
+
|
|
428
|
+
Stashify's job is to abstract those providers and make the best use of the storage available to the user.
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
# Security & Privacy
|
|
433
|
+
|
|
434
|
+
Stashify is designed around a simple trust model:
|
|
435
|
+
|
|
436
|
+
```text
|
|
437
|
+
Trusted
|
|
438
|
+
│
|
|
439
|
+
▼
|
|
440
|
+
┌───────────┐
|
|
441
|
+
│ User Device│
|
|
442
|
+
└─────┬─────┘
|
|
443
|
+
│
|
|
444
|
+
encrypted data
|
|
445
|
+
│
|
|
446
|
+
┌───────┴───────┐
|
|
447
|
+
▼ ▼
|
|
448
|
+
Telegram Discord
|
|
449
|
+
untrusted untrusted
|
|
450
|
+
storage storage
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Principles
|
|
454
|
+
|
|
455
|
+
**Local-first encryption**
|
|
456
|
+
|
|
457
|
+
Plaintext files are processed locally before being uploaded.
|
|
458
|
+
|
|
459
|
+
**Untrusted providers**
|
|
460
|
+
|
|
461
|
+
Storage providers are treated as storage infrastructure, not trusted holders of plaintext data.
|
|
462
|
+
|
|
463
|
+
**No custom cryptography**
|
|
464
|
+
|
|
465
|
+
Stashify uses established cryptographic implementations.
|
|
466
|
+
|
|
467
|
+
**Authenticated data**
|
|
468
|
+
|
|
469
|
+
Encrypted chunks should provide confidentiality and integrity.
|
|
470
|
+
|
|
471
|
+
**Minimal exposure**
|
|
472
|
+
|
|
473
|
+
Provider APIs should receive only the information required to store and retrieve encrypted data.
|
|
474
|
+
|
|
475
|
+
**Open source**
|
|
476
|
+
|
|
477
|
+
The codebase is intended to remain publicly auditable.
|
|
478
|
+
|
|
479
|
+
> Stashify is early-stage software. Do not rely on it for critical backups until the security model, implementation, and recovery mechanisms have been thoroughly reviewed.
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
# Architecture
|
|
484
|
+
|
|
485
|
+
At a high level:
|
|
486
|
+
|
|
487
|
+
```text
|
|
488
|
+
┌───────▼───────┐
|
|
489
|
+
│ CLI │
|
|
490
|
+
└───────┬───────┘
|
|
491
|
+
│
|
|
492
|
+
┌───────▼───────┐
|
|
493
|
+
│ Core Engine │
|
|
494
|
+
└───────┬───────┘
|
|
495
|
+
│
|
|
496
|
+
┌──────────────────┼──────────────────┐
|
|
497
|
+
│ │ │
|
|
498
|
+
▼ ▼ ▼
|
|
499
|
+
Encryption Chunking Metadata
|
|
500
|
+
│ │ │
|
|
501
|
+
└──────────────────┼──────────────────┘
|
|
502
|
+
│
|
|
503
|
+
┌───────▼───────┐
|
|
504
|
+
│ Storage Router│
|
|
505
|
+
└───────┬───────┘
|
|
506
|
+
│
|
|
507
|
+
┌────────────┼────────────┐
|
|
508
|
+
▼ ▼ ▼
|
|
509
|
+
Telegram Discord Future
|
|
510
|
+
Providers
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
The architecture intentionally separates:
|
|
514
|
+
|
|
515
|
+
* User interface
|
|
516
|
+
* Core storage logic
|
|
517
|
+
* Cryptography
|
|
518
|
+
* Chunking
|
|
519
|
+
* Metadata
|
|
520
|
+
* Job execution
|
|
521
|
+
* Provider implementations
|
|
522
|
+
|
|
523
|
+
This allows the system to evolve without coupling the entire codebase to a specific provider.
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
# Project Status
|
|
528
|
+
|
|
529
|
+
> **Stashify is currently in early development.**
|
|
530
|
+
|
|
531
|
+
The architecture is being actively developed and APIs may change significantly.
|
|
532
|
+
|
|
533
|
+
| Component | Status |
|
|
534
|
+
| ---------------------- | ----------- |
|
|
535
|
+
| Project architecture | In progress |
|
|
536
|
+
| Python CLI | In progress |
|
|
537
|
+
| Encryption | Implemented |
|
|
538
|
+
| Chunking | Implemented |
|
|
539
|
+
| Manifest / metadata | Implemented |
|
|
540
|
+
| Provider abstraction | In progress |
|
|
541
|
+
| Telegram provider | Implemented |
|
|
542
|
+
| Discord provider | Implemented |
|
|
543
|
+
| Async job engine | Implemented |
|
|
544
|
+
| Resumable transfers | Planned |
|
|
545
|
+
| Multi-provider routing | Planned |
|
|
546
|
+
| Verification | Planned |
|
|
547
|
+
| Repair / recovery | Future |
|
|
548
|
+
| Additional providers | Future |
|
|
549
|
+
|
|
550
|
+
Features marked **Planned** or **Future** should not be considered implemented.
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
# Development
|
|
555
|
+
|
|
556
|
+
Stashify is built with Python and is designed around asynchronous I/O.
|
|
557
|
+
|
|
558
|
+
The project aims to keep the core storage engine independent from its user interfaces and provider implementations.
|
|
559
|
+
|
|
560
|
+
A typical architecture is:
|
|
561
|
+
|
|
562
|
+
```text
|
|
563
|
+
UI
|
|
564
|
+
│
|
|
565
|
+
└── CLI
|
|
566
|
+
│
|
|
567
|
+
▼
|
|
568
|
+
Core Storage Engine
|
|
569
|
+
│
|
|
570
|
+
├── Crypto
|
|
571
|
+
├── Chunking
|
|
572
|
+
├── Metadata
|
|
573
|
+
├── Jobs
|
|
574
|
+
└── Storage Router
|
|
575
|
+
│
|
|
576
|
+
├── Telegram
|
|
577
|
+
├── Discord
|
|
578
|
+
└── Future Providers
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
# Contributing
|
|
586
|
+
|
|
587
|
+
Contributions are welcome.
|
|
588
|
+
|
|
589
|
+
Some areas where contributions will be especially useful:
|
|
590
|
+
|
|
591
|
+
* Storage providers
|
|
592
|
+
* Encryption and security review
|
|
593
|
+
* Chunking and transfer reliability
|
|
594
|
+
* TUI/UX improvements
|
|
595
|
+
* Testing
|
|
596
|
+
* Documentation
|
|
597
|
+
* Performance
|
|
598
|
+
* Cross-platform support
|
|
599
|
+
|
|
600
|
+
Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request.
|
|
601
|
+
|
|
602
|
+
If you discover a potential security vulnerability, please follow the project's security reporting process rather than publicly disclosing the issue immediately.
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
# Roadmap
|
|
607
|
+
|
|
608
|
+
The long-term goal is to turn Stashify into a flexible encrypted storage layer that can sit on top of almost any suitable storage provider.
|
|
609
|
+
|
|
610
|
+
### Near term
|
|
611
|
+
|
|
612
|
+
* [x] Core encryption pipeline
|
|
613
|
+
* [x] Chunking
|
|
614
|
+
* [ ] SQLite metadata
|
|
615
|
+
* [x] Telegram provider
|
|
616
|
+
* [x] Discord provider
|
|
617
|
+
* [x] Async transfer system
|
|
618
|
+
* [ ] Resumable uploads
|
|
619
|
+
|
|
620
|
+
### Medium term
|
|
621
|
+
|
|
622
|
+
* [ ] Multi-provider routing
|
|
623
|
+
* [ ] Replication
|
|
624
|
+
* [ ] Integrity verification
|
|
625
|
+
* [ ] Recovery/repair
|
|
626
|
+
* [ ] Provider health monitoring
|
|
627
|
+
|
|
628
|
+
### Long term
|
|
629
|
+
|
|
630
|
+
* [ ] S3-compatible providers
|
|
631
|
+
* [ ] Backblaze B2
|
|
632
|
+
* [ ] Google Drive
|
|
633
|
+
* [ ] WebDAV
|
|
634
|
+
* [ ] Local filesystem backend
|
|
635
|
+
* [ ] Additional community providers
|
|
636
|
+
* [ ] Advanced redundancy strategies
|
|
637
|
+
|
|
638
|
+
The roadmap is intentionally flexible and will evolve as the project matures.
|
|
639
|
+
|
|
640
|
+
---
|
|
641
|
+
|
|
642
|
+
# License
|
|
643
|
+
|
|
644
|
+
Stashify is released under the **MIT License**.
|
|
645
|
+
|
|
646
|
+
See [LICENSE](LICENSE) for the full license text.
|
|
647
|
+
|
|
648
|
+
---
|
|
649
|
+
|
|
650
|
+
<p align="center">
|
|
651
|
+
<strong>Stashify</strong><br>
|
|
652
|
+
<sub>Your files. Your keys. Your storage.</sub>
|
|
653
|
+
</p>
|