mycloudctl 1.0.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.
- mycloudctl-1.0.0/PKG-INFO +377 -0
- mycloudctl-1.0.0/README.md +367 -0
- mycloudctl-1.0.0/cli/__init__.py +2 -0
- mycloudctl-1.0.0/cli/__main__.py +138 -0
- mycloudctl-1.0.0/cli/api.py +323 -0
- mycloudctl-1.0.0/cli/commands/__init__.py +1 -0
- mycloudctl-1.0.0/cli/commands/auth.py +234 -0
- mycloudctl-1.0.0/cli/commands/batch.py +175 -0
- mycloudctl-1.0.0/cli/commands/favorites.py +35 -0
- mycloudctl-1.0.0/cli/commands/files.py +356 -0
- mycloudctl-1.0.0/cli/commands/folders.py +200 -0
- mycloudctl-1.0.0/cli/commands/notifications.py +79 -0
- mycloudctl-1.0.0/cli/commands/prefs.py +72 -0
- mycloudctl-1.0.0/cli/commands/profile.py +157 -0
- mycloudctl-1.0.0/cli/commands/search.py +78 -0
- mycloudctl-1.0.0/cli/commands/servers.py +95 -0
- mycloudctl-1.0.0/cli/commands/share.py +392 -0
- mycloudctl-1.0.0/cli/commands/stash.py +92 -0
- mycloudctl-1.0.0/cli/commands/storage.py +88 -0
- mycloudctl-1.0.0/cli/config.py +87 -0
- mycloudctl-1.0.0/cli/ui/__init__.py +1 -0
- mycloudctl-1.0.0/cli/ui/table.py +112 -0
- mycloudctl-1.0.0/cli/ui/tree.py +56 -0
- mycloudctl-1.0.0/mycloudctl.egg-info/PKG-INFO +377 -0
- mycloudctl-1.0.0/mycloudctl.egg-info/SOURCES.txt +29 -0
- mycloudctl-1.0.0/mycloudctl.egg-info/dependency_links.txt +1 -0
- mycloudctl-1.0.0/mycloudctl.egg-info/entry_points.txt +2 -0
- mycloudctl-1.0.0/mycloudctl.egg-info/requires.txt +3 -0
- mycloudctl-1.0.0/mycloudctl.egg-info/top_level.txt +1 -0
- mycloudctl-1.0.0/pyproject.toml +23 -0
- mycloudctl-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mycloudctl
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official CLI for myCloud — your personal cloud storage
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: typer[all]>=0.12
|
|
8
|
+
Requires-Dist: rich>=13.7
|
|
9
|
+
Requires-Dist: httpx>=0.27
|
|
10
|
+
|
|
11
|
+
# myCloud
|
|
12
|
+
|
|
13
|
+
A full-stack personal cloud platform built with Flask + MySQL that supports file storage, folder management, sharing (direct invite + token links + batch sharing), previews, stash/recovery workflows, monitoring dashboards, and optional storage-node workflows.
|
|
14
|
+
|
|
15
|
+
## Table of Contents
|
|
16
|
+
|
|
17
|
+
- Overview
|
|
18
|
+
- Core Features
|
|
19
|
+
- Project Structure
|
|
20
|
+
- Architecture
|
|
21
|
+
- Infrastructure and Runtime Topology
|
|
22
|
+
- Data and Schema Evolution
|
|
23
|
+
- Environment Configuration
|
|
24
|
+
- Local Development Setup
|
|
25
|
+
- Production Deployment (Linux VPS)
|
|
26
|
+
- Operations and Monitoring
|
|
27
|
+
- Security Notes
|
|
28
|
+
- Troubleshooting
|
|
29
|
+
- Release/Push Checklist
|
|
30
|
+
|
|
31
|
+
## Overview
|
|
32
|
+
|
|
33
|
+
myCloud is a web application for managing personal cloud files with:
|
|
34
|
+
|
|
35
|
+
- User auth (username/password and social auth)
|
|
36
|
+
- Upload/download and folder operations
|
|
37
|
+
- Advanced sharing:
|
|
38
|
+
- direct user invites
|
|
39
|
+
- token-based share links
|
|
40
|
+
- batch share links for mixed files/folders
|
|
41
|
+
- Shared library actions (preview, copy to MyCloud, leave share, favorites)
|
|
42
|
+
- Stash workflow for temporary removal/recovery
|
|
43
|
+
- Node-aware storage metadata and optional node-side GUI tooling
|
|
44
|
+
- Monitoring endpoints for system, services, app activity, and product analytics
|
|
45
|
+
|
|
46
|
+
## Core Features
|
|
47
|
+
|
|
48
|
+
### Account and Auth
|
|
49
|
+
|
|
50
|
+
- Registration, login, logout, password reset, email verification
|
|
51
|
+
- Two-factor code flow endpoints
|
|
52
|
+
- OAuth providers:
|
|
53
|
+
- Google
|
|
54
|
+
- GitHub
|
|
55
|
+
|
|
56
|
+
### File and Folder Management
|
|
57
|
+
|
|
58
|
+
- Upload files, create folders
|
|
59
|
+
- Rename, move, delete, stash, unstash
|
|
60
|
+
- Bulk operations: move/delete/download/share/stash/unstash/remove-share/add-to-mycloud
|
|
61
|
+
- Preview support for images/video/audio/PDF/code/docx (web UI behavior)
|
|
62
|
+
|
|
63
|
+
### Sharing
|
|
64
|
+
|
|
65
|
+
- Direct item sharing with permission updates
|
|
66
|
+
- Share links for file/folder
|
|
67
|
+
- Batch share link generation and acceptance
|
|
68
|
+
- Unified share removal APIs
|
|
69
|
+
- Invite response APIs (accept/decline + optional mute sender)
|
|
70
|
+
- Muted user management for invite control
|
|
71
|
+
|
|
72
|
+
### UX and Settings
|
|
73
|
+
|
|
74
|
+
- Preferences APIs and sync endpoints
|
|
75
|
+
- Theme/view mode handling in frontend assets
|
|
76
|
+
- Profile picture upload/remove
|
|
77
|
+
- Notifications API + mark-read/hide
|
|
78
|
+
|
|
79
|
+
### Monitoring and Analytics
|
|
80
|
+
|
|
81
|
+
- System metrics API (CPU/RAM/disk/network/load)
|
|
82
|
+
- Service status/log APIs (nginx/gunicorn/ssh where available)
|
|
83
|
+
- Application activity monitor (recent events/endpoints)
|
|
84
|
+
- Product analytics overview/trends
|
|
85
|
+
|
|
86
|
+
## Project Structure
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
.
|
|
90
|
+
|- app.py # Main Flask + Socket.IO server
|
|
91
|
+
|- services.py # Linux service/log monitoring helpers
|
|
92
|
+
|- monitor.py # System monitor abstraction + local implementation
|
|
93
|
+
|- app_monitor.py # App-level activity monitoring
|
|
94
|
+
|- data_monitor.py # Data/storage monitoring
|
|
95
|
+
|- product_analytics.py # Product usage analytics
|
|
96
|
+
|- db_update_nodes.py # DB schema updates for storage node support
|
|
97
|
+
|- migrate_shares_table.py # Migration to unified shares table
|
|
98
|
+
|- setup_batch_sharing_db.py # Batch share schema bootstrap
|
|
99
|
+
|- mycloud_node_gui.py # Optional node desktop GUI client
|
|
100
|
+
|- deploy_changed_files.ps1 # Incremental deployment helper (scp/ssh)
|
|
101
|
+
|- templates/ # Flask templates
|
|
102
|
+
|- static/ # Frontend JS/CSS/assets
|
|
103
|
+
|- uploads/ # Runtime user uploads (ignored from git)
|
|
104
|
+
|- requirements.txt # Python dependencies
|
|
105
|
+
|- .env.example # Environment variable template
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Architecture
|
|
109
|
+
|
|
110
|
+
### Application Layer
|
|
111
|
+
|
|
112
|
+
- Framework: Flask
|
|
113
|
+
- Real-time channel: Flask-SocketIO
|
|
114
|
+
- Reverse-proxy awareness: Werkzeug ProxyFix
|
|
115
|
+
- Session + auth logic + routing in a single main server file (`app.py`)
|
|
116
|
+
|
|
117
|
+
### Real-time / Socket Layer
|
|
118
|
+
|
|
119
|
+
Socket handlers are registered in `app.py` for:
|
|
120
|
+
|
|
121
|
+
- node registration
|
|
122
|
+
- node disconnect
|
|
123
|
+
- chunked download transfer
|
|
124
|
+
|
|
125
|
+
### Persistence Layer
|
|
126
|
+
|
|
127
|
+
- Primary DB: MySQL (`mysql-connector-python`)
|
|
128
|
+
- Schema support scripts:
|
|
129
|
+
- `migrate_shares_table.py` creates/migrates a unified `shares` model
|
|
130
|
+
- `setup_batch_sharing_db.py` provisions `batch_share_links` and `batch_share_items`
|
|
131
|
+
- `db_update_nodes.py` provisions `storage_nodes` and extends `files` with node metadata
|
|
132
|
+
|
|
133
|
+
### Frontend Layer
|
|
134
|
+
|
|
135
|
+
- Server-rendered Jinja templates in `templates/`
|
|
136
|
+
- Static JS/CSS in `static/`
|
|
137
|
+
- Rich shared-files interactions include:
|
|
138
|
+
- list/grid sort/filter/view
|
|
139
|
+
- direct invite modal and muted-users modal
|
|
140
|
+
- multi-select action toolbar
|
|
141
|
+
|
|
142
|
+
## Infrastructure and Runtime Topology
|
|
143
|
+
|
|
144
|
+
Typical production topology:
|
|
145
|
+
|
|
146
|
+
- Browser clients -> Nginx reverse proxy -> Gunicorn/Eventlet Flask-SocketIO app
|
|
147
|
+
- App server -> MySQL database
|
|
148
|
+
- Optional storage nodes -> connect/register via Socket.IO events
|
|
149
|
+
|
|
150
|
+
`services.py` is designed for Linux hosts with optional `systemctl` / `journalctl` access and can inspect:
|
|
151
|
+
|
|
152
|
+
- nginx
|
|
153
|
+
- gunicorn (unit configurable via `MONITOR_GUNICORN_SERVICE`)
|
|
154
|
+
- ssh/sshd
|
|
155
|
+
|
|
156
|
+
## Data and Schema Evolution
|
|
157
|
+
|
|
158
|
+
### Node/Storage schema updates
|
|
159
|
+
|
|
160
|
+
Run once when enabling node-aware storage metadata:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
python db_update_nodes.py
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
What it does:
|
|
167
|
+
|
|
168
|
+
- Creates `storage_nodes`
|
|
169
|
+
- Adds `files.storage_mode` (default `central`) if missing
|
|
170
|
+
- Adds `files.node_id` FK to `storage_nodes(id)` if missing
|
|
171
|
+
|
|
172
|
+
### Shares migration
|
|
173
|
+
|
|
174
|
+
Run once to unify old sharing models:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
python migrate_shares_table.py
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
What it does:
|
|
181
|
+
|
|
182
|
+
- Creates unified `shares` table if missing
|
|
183
|
+
- Migrates data from older share tables/links when present
|
|
184
|
+
|
|
185
|
+
### Batch share schema bootstrap
|
|
186
|
+
|
|
187
|
+
Run once to enable batch share links:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
python setup_batch_sharing_db.py
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
What it does:
|
|
194
|
+
|
|
195
|
+
- Creates `batch_share_links`
|
|
196
|
+
- Creates `batch_share_items` with FK cascade
|
|
197
|
+
|
|
198
|
+
## Environment Configuration
|
|
199
|
+
|
|
200
|
+
Copy the template and fill values:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
cp .env.example .env
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
On Windows PowerShell:
|
|
207
|
+
|
|
208
|
+
```powershell
|
|
209
|
+
Copy-Item .env.example .env
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Key variables
|
|
213
|
+
|
|
214
|
+
- Flask/runtime:
|
|
215
|
+
- `FLASK_SECRET_KEY`
|
|
216
|
+
- `FLASK_HOST`
|
|
217
|
+
- `FLASK_PORT`
|
|
218
|
+
- `FLASK_DEBUG`
|
|
219
|
+
- `APP_BASE_URL`
|
|
220
|
+
- Session hardening:
|
|
221
|
+
- `SESSION_COOKIE_SECURE`
|
|
222
|
+
- `SESSION_COOKIE_SAMESITE`
|
|
223
|
+
- `SESSION_LIFETIME_HOURS`
|
|
224
|
+
- Database:
|
|
225
|
+
- `DB_HOST`
|
|
226
|
+
- `DB_USER`
|
|
227
|
+
- `DB_PASSWORD`
|
|
228
|
+
- `DB_NAME`
|
|
229
|
+
- OAuth/API:
|
|
230
|
+
- `GOOGLE_CLIENT_ID`
|
|
231
|
+
- `GOOGLE_CLIENT_SECRET`
|
|
232
|
+
- `GOOGLE_API_KEY`
|
|
233
|
+
- `GITHUB_CLIENT_ID`
|
|
234
|
+
- `GITHUB_CLIENT_SECRET`
|
|
235
|
+
- `MONITOR_API_KEY`
|
|
236
|
+
- SMTP:
|
|
237
|
+
- `SMTP_SENDER_EMAIL`
|
|
238
|
+
- `SMTP_SENDER_PASSWORD`
|
|
239
|
+
- Storage and sockets:
|
|
240
|
+
- `UPLOAD_FOLDER`
|
|
241
|
+
- `ACCOUNT_STORAGE_LIMIT_GB`
|
|
242
|
+
- `SOCKETIO_CORS_ORIGINS`
|
|
243
|
+
- Monitoring/services:
|
|
244
|
+
- `MONITOR_GUNICORN_SERVICE`
|
|
245
|
+
|
|
246
|
+
## Local Development Setup
|
|
247
|
+
|
|
248
|
+
## 1) Create virtual environment
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
python -m venv .venv
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Windows PowerShell:
|
|
255
|
+
|
|
256
|
+
```powershell
|
|
257
|
+
.\.venv\Scripts\Activate.ps1
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## 2) Install dependencies
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
pip install -r requirements.txt
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## 3) Configure `.env`
|
|
267
|
+
|
|
268
|
+
Set a strong `FLASK_SECRET_KEY` and valid DB credentials.
|
|
269
|
+
|
|
270
|
+
## 4) Optional DB setup/migrations
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
python db_update_nodes.py
|
|
274
|
+
python migrate_shares_table.py
|
|
275
|
+
python setup_batch_sharing_db.py
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## 5) Run app
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
python app.py
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Server binds to:
|
|
285
|
+
|
|
286
|
+
- host: `FLASK_HOST` (default `0.0.0.0`)
|
|
287
|
+
- port: `FLASK_PORT` (default `5000`)
|
|
288
|
+
|
|
289
|
+
## Production Deployment (Linux VPS)
|
|
290
|
+
|
|
291
|
+
### Recommended stack
|
|
292
|
+
|
|
293
|
+
- Nginx (reverse proxy)
|
|
294
|
+
- Gunicorn + eventlet worker class for Socket.IO compatibility
|
|
295
|
+
- systemd service for app process
|
|
296
|
+
- MySQL reachable from app host
|
|
297
|
+
|
|
298
|
+
Example command:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
gunicorn -k eventlet -w 1 -b 0.0.0.0:5000 app:app
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Note: For Flask-SocketIO apps, eventlet/gevent-compatible deployment is recommended.
|
|
305
|
+
|
|
306
|
+
### Incremental deploy helper
|
|
307
|
+
|
|
308
|
+
`deploy_changed_files.ps1` can:
|
|
309
|
+
|
|
310
|
+
- detect changed deployable files from git status
|
|
311
|
+
- fallback to `changed_files.txt` when needed
|
|
312
|
+
- upload files via `scp` and pre-create remote directories via `ssh`
|
|
313
|
+
- optionally restart systemd service
|
|
314
|
+
|
|
315
|
+
Example:
|
|
316
|
+
|
|
317
|
+
```powershell
|
|
318
|
+
.\deploy_changed_files.ps1 -RestartService -ServiceName mycloud
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Before using in another environment, adjust script parameters:
|
|
322
|
+
|
|
323
|
+
- `KeyPath`
|
|
324
|
+
- `User`
|
|
325
|
+
- `ServerHost`
|
|
326
|
+
- `RemoteRoot`
|
|
327
|
+
- `ServiceName`
|
|
328
|
+
|
|
329
|
+
## Operations and Monitoring
|
|
330
|
+
|
|
331
|
+
Monitoring routes are exposed in the app for:
|
|
332
|
+
|
|
333
|
+
- system metrics
|
|
334
|
+
- service status/logs
|
|
335
|
+
- app-level statistics and recent endpoint activity
|
|
336
|
+
- product analytics summaries/trends
|
|
337
|
+
|
|
338
|
+
For protected monitoring APIs, provide configured `MONITOR_API_KEY` where required by your runtime policy.
|
|
339
|
+
|
|
340
|
+
## Security Notes
|
|
341
|
+
|
|
342
|
+
- Never commit `.env`, private keys, or runtime upload content.
|
|
343
|
+
- Rotate any credentials that were ever hardcoded/shared.
|
|
344
|
+
- Keep `FLASK_SECRET_KEY` long and random.
|
|
345
|
+
- Enforce HTTPS in production and keep `SESSION_COOKIE_SECURE=true`.
|
|
346
|
+
- Restrict CORS origins via `SOCKETIO_CORS_ORIGINS`.
|
|
347
|
+
|
|
348
|
+
## Troubleshooting
|
|
349
|
+
|
|
350
|
+
### App fails at startup with secret key error
|
|
351
|
+
|
|
352
|
+
- Ensure `FLASK_SECRET_KEY` is set in `.env`.
|
|
353
|
+
|
|
354
|
+
### DB connection/migration errors
|
|
355
|
+
|
|
356
|
+
- Verify `DB_HOST`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`
|
|
357
|
+
- Ensure MySQL user has schema alter/create permissions
|
|
358
|
+
|
|
359
|
+
### Socket issues behind proxy
|
|
360
|
+
|
|
361
|
+
- Ensure proxy supports websocket upgrade
|
|
362
|
+
- Use an eventlet-compatible Gunicorn setup
|
|
363
|
+
|
|
364
|
+
### Monitoring service status unavailable
|
|
365
|
+
|
|
366
|
+
- Confirm Linux host has `systemctl`/`journalctl`
|
|
367
|
+
- Verify service names (`MONITOR_GUNICORN_SERVICE`)
|
|
368
|
+
|
|
369
|
+
## Release/Push Checklist
|
|
370
|
+
|
|
371
|
+
- `.env` excluded from git
|
|
372
|
+
- `uploads/`, `build/`, `dist/`, `__pycache__/`, `.venv/` excluded from git
|
|
373
|
+
- `requirements.txt` up to date
|
|
374
|
+
- `.env.example` present and current
|
|
375
|
+
- Run schema scripts on target environment before first production run
|
|
376
|
+
|
|
377
|
+
---
|