SJTU Netdisk command line interface
Project description
jdisk
A CLI tool for SJTU Netdisk
โ QR Code Authentication - Simple and reliable authentication method
โ Complete File Operations - Upload, download, list, navigate directories
โ Smart Session Management - Persistent authentication with auto-renewal
๐ Quick Start
Installation
Install from PyPI
# Install via pip
pip install jdisk
jdisk --help
or
# Install via uv
uv tool install jdisk
jdisk --help
Install from Source
# Clone the repository
git clone https://github.com/chengjilai/jdisk.git
cd jdisk
# Install dependencies using pixi
pixi install
# Run the CLI tool directly
pixi run python jdisk.py --help
# Or create a symbolic link for system-wide access
chmod +x jdisk.py
ln -sf "$(pwd)/jdisk.py" ~/.local/bin/jdisk
# Verify installation
jdisk --help
First Time Authentication
QR Code Authentication ๐ฑ
jdisk auth
Process:
- QR code displayed in terminal
- Scan with My SJTU mobile
๐ Usage Examples
Basic Operations
# Authentication
jdisk auth # QR code authentication
# File Management
jdisk list # List root directory
jdisk list docs/ # List specific directory
jdisk ls # Short form of list
jdisk ls docs/ # List docs/ directory
# File Operations
jdisk upload file.txt # Upload to root directory
jdisk upload file.txt docs/ # Upload to specific directory
jdisk download file.txt # Download from root directory
jdisk download docs/file.txt # Download from specific directory
Advanced Usage
# File operations with paths
jdisk upload ./local/file.txt /remote/path/
jdisk download /remote/file.txt ./local/
jdisk ls /folder/subfolder/
๐ Key Features
Authentication
- ๐พ Session Persistence: Save and reuse authentication
- ๐ Auto-Refresh: QR codes refresh to prevent expiration
File Operations
- ๐ค Chunked Upload: Efficient large file uploads with progress
- ๐ฅ Direct Download: Fast downloads via S3 presigned URLs
- ๐ Directory Navigation: List and navigate directories
- ๐ Secure Connections: HTTPS/TLS for all communications
User Experience
- ๐จ Terminal-Friendly: Optimized for command-line usage
- ๐ฑ Mobile Support: QR code scanning with mobile apps
๐ง Authentication Method
QR Code Authentication ๐ฑ
Features:
- โ Auto-refresh prevents expiration
- โ Server-provided security signatures
- โ Real-time WebSocket communication
How it works:
- Generate unique QR code with server signature
- Scan with SJTU mobile app OR visit URL in browser
- Login through SJTU JAccount website
- System automatically captures authentication
- QR code refreshes every 50 seconds to prevent expiration
User Experience:
๐ฑ QR Code Authentication for SJTU Netdisk ๐ฒ QR Code Generated: [... QR code displayed in terminal ...]
๐ Project Structure
jdisk/
โโโ src/ # Source code directory
โ โโโ jdisk/ # Main package
โ โโโ __init__.py # Package initialization
โ โโโ auth.py # Authentication classes
โ โโโ client.py # Main API client
โ โโโ cli.py # CLI interface
โ โโโ constants.py # API constants and URLs
โ โโโ download.py # File download functionality
โ โโโ exceptions.py # Custom exception classes
โ โโโ models.py # Data models
โ โโโ jdisk.py # Main CLI entry point
โ โโโ upload.py # File upload functionality
โโโ pyproject.toml # Package configuration
โโโ README.md
โโโ LICENSE
โโโ pixi.lock
โโโ .git
โโโ .gitignore
๐ ๏ธ Dependencies
[dependencies]
requests
qrcode
websocket-client
๐๏ธ Technical Architecture
QR Code Authentication Flow
- Extract UUID from SJTU login page
- Establish WebSocket connection to jaccount.sjtu.edu.cn
- Request QR code signature from server
- Generate QR code with server-provided sig/ts values
- Display QR code and URL in terminal
- Monitor WebSocket for authentication events
- Auto-refresh QR code every 50 seconds
- Capture JAAuthCookie upon successful login
- Complete authentication process
Authentication Security
- Server-provided signatures: QR codes use proper cryptographic signatures from SJTU servers
- Auto-refresh mechanism: Prevents QR code expiration with periodic updates every 50 seconds
- Secure WebSocket communication: Real-time, encrypted communication channels
- Temporary sessions: Unique UUID for each authentication session
- Automatic cleanup: Sessions expire and clean up automatically
- Correct Space ID Handling: QR code authentication now generates sessions with proper
space3jvslhfm2b78tspace_id
Space Info API Handling
The space info API has been FIXED to handle both response formats:
Success Response Format (Current):
{
"libraryId": "smh2ax67srucy60s",
"spaceId": "space3jvslhfm2b78t",
"accessToken": "acctk019e278500mgm8qjucwuxta2j8swqemzv38ezcn2dzyqxm8ny2agd36pj6zfanmrhuh8way2vgjfs4asdph6s9b69z6zrjy27ulcmjdzqhv8yylpc56dbe8fc",
"expiresIn": 1800
}
Response Analysis:
- Status Field Not Required: The API doesn't return a
"status"field in successful responses - Correct Format: All required fields are directly available (
library_id,space_id,accessToken) - Proper Access Token: Access token in format
acctk...(SJTU-specific token) - Expires In: Token has 30-minute expiration for security
Session Structure
QR Code Authentication:
{
"ja_auth_cookie": "...",
"user_token": "...",
"library_id": "smh2...",
"space_id": "space...",
"access_token": "acctk...", // SJTU-specific access token
"username": "..."
}
File Upload Process
Three-step chunked upload similar to AWS S3:
- Initiate: Request upload permission and S3 URLs
- Upload: Upload file chunks to S3 using provided credentials
- Confirm: Verify upload completion and finalize file
File Download Process
- Request: Get download URL from SJTU Netdisk API
- Redirect: Follow 302 redirect to S3 presigned URL
- Download: Direct download from AWS S3 with progress tracking
๐ ๏ธ API Reference
Base Configuration
Base URL: https://pan.sjtu.edu.cn
Authentication: JAAuthCookie + OAuth 2.0
Storage Backend: AWS S3-compatible (s3pan.jcloud.sjtu.edu.cn)
Authentication Endpoints
JAccount Authentication via JAAuthCookie
The SJTU Netdisk uses JAAuthCookie for authentication, which can be obtained from browser cookies after logging into pan.sjtu.edu.cn.
Authentication Endpoint:
GET https://jaccount.sjtu.edu.cn/oauth2/authorize/xpw8ou8y
Token Exchange:
POST https://pan.sjtu.edu.cn/user/v1/sign-in/verify-account-login/xpw8ou8y
Request Body:
{
"credential": "{authorization_code}"
}
Response:
{
"userToken": "128-character token",
"userId": "user_id",
"organizations": [
{
"libraryId": "library_id",
"orgUser": {
"nickname": "username"
}
}
]
}
Personal Space Information:
POST https://pan.sjtu.edu.cn/user/v1/space/1/personal
Request Parameters:
user_token: 128-character user token
Response:
{
"status": 0,
"libraryId": "library_id",
"spaceId": "space_id",
"accessToken": "access_token",
"expiresIn": 3600,
"message": "success"
}
File Upload API
The upload process uses a three-step chunked approach similar to AWS S3 multipart upload.
Step 1: Initiate Upload
POST /api/v1/file/{library_id}/{space_id}/{path}?access_token={access_token}&multipart=null&conflict_resolution_strategy={strategy}
Parameters:
library_id: User's library IDspace_id: User's space IDpath: Remote file path (URL encoded)access_token: Valid access tokenmultipart: Fixed value "null"conflict_resolution_strategy: "rename" or "overwrite"
Request Body:
{
"partNumberRange": [1, 2, 3]
}
Response:
{
"confirmKey": "unique_confirmation_key",
"domain": "s3pan.jcloud.sjtu.edu.cn",
"path": "/tced-private-{random}-sjtu/{library_id}/{confirmKey}.txt",
"uploadId": "upload_id",
"parts": {
"1": {
"headers": {
"x-amz-date": "20251011T025800Z",
"x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"authorization": "AWS4-HMAC-SHA256 Credential=..."
}
}
},
"expiration": "2025-10-11T03:13:00.569Z"
}
Step 2: Upload Chunks
PUT https://{domain}{path}?uploadId={uploadId}&partNumber={part_number}
Headers:
Content-Type:application/octet-streamContent-Length: Chunk size in bytesAccept:*/*Accept-Encoding:gzip, deflate, brAccept-Language:zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7x-amz-date: From step 1 responseauthorization: From step 1 responsex-amz-content-sha256: From step 1 response
Request Body: Binary chunk data
Step 3: Confirm Upload
POST /api/v1/file/{library_id}/{space_id}/{confirmKey}?access_token={access_token}&confirm=null&conflict_resolution_strategy={strategy}
Parameters:
confirmKey: From step 1 responseaccess_token: Valid access tokenconfirm: Fixed value "null"conflict_resolution_strategy: "rename" or "overwrite"
Response:
{
"path": ["folder", "filename.txt"],
"name": "filename.txt",
"type": "file",
"creationTime": "2025-10-11T02:58:15.461Z",
"modificationTime": "2025-10-11T02:58:15.461Z",
"contentType": "text/plain",
"size": "391",
"eTag": "\"f255a82c43f56b46de4057cc5a393430-1\"",
"crc64": "11953636811276951993",
"metaData": {},
"isOverwritten": false,
"virusAuditStatus": 0,
"sensitiveWordAuditStatus": 0,
"previewByDoc": true,
"previewByCI": true,
"previewAsIcon": false,
"fileType": "text"
}
File Download API
Downloads are handled through a redirect mechanism that provides AWS S3 presigned URLs.
Download Request
GET /api/v1/file/{library_id}/{space_id}/{path}?access_token={access_token}&download=true
Parameters:
library_id: User's library IDspace_id: User's space IDpath: Remote file pathaccess_token: Valid access tokendownload: Fixed value "true"
Response Flow:
- 302 Redirect to AWS S3 presigned URL
- S3 URL contains AWS4-HMAC-SHA256 signature with 2-hour expiration
- Direct Download from
s3pan.jcloud.sjtu.edu.cn
S3 URL Pattern:
https://s3pan.jcloud.sjtu.edu.cn/tced-private-{random}-sjtu/{library_id}/{file_id}.txt?
X-Amz-Algorithm=AWS4-HMAC-SHA256&
X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&
X-Amz-Credential={credentials}&
X-Amz-Date={timestamp}&
X-Amz-Expires=7200&
X-Amz-Signature={signature}&
X-Amz-SignedHeaders=host&
response-content-disposition=inline%3B%20filename%2A%3DUTF-8%27%27{filename}
Directory Listing API
List Directory Contents
GET /api/v1/directory/{library_id}/{space_id}/{path}?access_token={access_token}&page={page}&page_size={size}
Parameters:
library_id: User's library IDspace_id: User's space IDpath: Directory path (use "/" for root)access_token: Valid access tokenpage: Page number (default: 1)page_size: Items per page (default: 50)
Response:
{
"path": [""],
"contents": [
{
"name": "filename.txt",
"type": "file",
"size": "391",
"modificationTime": "2025-10-11T03:03:14.000Z",
"isDir": false
}
],
"fileCount": 1,
"subDirCount": 0,
"totalNum": 1
}
Important Notes
Authentication Requirements
- Campus Network: SJTU Netdisk typically requires connection through campus network or VPN
- QR Code Authentication: Scan with SJTU mobile app or visit authentication URL
- Session Management: Access tokens expire after 1 hour and need renewal
Upload Constraints
- Chunk Size: 4MB chunks recommended (4,194,304 bytes)
- Maximum Chunks: 50 chunks per upload session
- File Size Limit: ~200MB per file (50 chunks ร 4MB)
- Conflict Resolution: Supports "rename" and "overwrite" strategies
Download Features
- Streaming Support: HTTP Range requests for partial downloads
- Presigned URLs: S3 URLs are valid for 2 hours
- Integrity Verification: CRC64 and ETag provided for file verification
- Browser Compatible: Uses standard HTTP redirects
๐จ Troubleshooting
QR Code Issues
- "QR code expired": Fixed! Auto-refresh prevents expiration
- "Invalid signature": Fixed! Uses server-provided signatures
- "WebSocket timeout: Check network connection to SJTU servers
Authentication Issues
- "QR code scan failed": Try scanning again or visit the provided URL directly
- "Session expired": Run
jdisk authto re-authenticate - "Network error": Ensure VPN or campus network connection
File Operation Issues
- "Upload failed": Check file size and network connectivity
- "Download error": Verify file exists and permissions
- "Permission denied": Re-authenticate with valid session
Error Handling
- Status Codes: Standard HTTP status codes
- Error Format: JSON with
status,code,message, andrequestIdfields - Common Errors:
400 Bad Request: Missing parameters or invalid data401 Unauthorized: Invalid or expired access token404 Not Found: File or directory does not exist409 Conflict: File already exists (when conflict_resolution_strategy is not set)413 Payload Too Large: File exceeds size limits
๐ Development History
Latest Updates
- โ QR Code Authentication: Simple and reliable authentication method
- โ Server-Provided Signatures: QR codes use proper cryptographic signatures
- โ Auto-Refresh Mechanism: QR codes refresh every 50 seconds
- โ Enhanced WebSocket Handling: Improved real-time communication
- โ Comprehensive Testing: All features verified and working
๐ License
MIT License
๐ค Contributing
Contributions welcome! Please ensure:
- Code follows existing style
- Documentation is updated
- Features are backward compatible
๐ Enjoy using jdisk!
For issues, feature requests, or questions, please check the documentation or create an issue.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jdisk-0.1.9.tar.gz.
File metadata
- Download URL: jdisk-0.1.9.tar.gz
- Upload date:
- Size: 25.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3518eea53b063bc46f77660d57fb5c15bc7bdceabcd9e0c4058655b1920e858e
|
|
| MD5 |
b6e79fba668c66c03953bdb520c22ffb
|
|
| BLAKE2b-256 |
31af652ac5da22b1cc89e5e538b10831058abfb8198b7ccf45b28f6df3e012e6
|
File details
Details for the file jdisk-0.1.9-py3-none-any.whl.
File metadata
- Download URL: jdisk-0.1.9-py3-none-any.whl
- Upload date:
- Size: 31.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b372f3ad75eba044aad53ffb7f6369cb1a54132dc827a3e2baea471c7c86582c
|
|
| MD5 |
6b8daae211b4520002572e788464cae2
|
|
| BLAKE2b-256 |
b4f42b8106b8b4711d722f53229e760c84f7d0ed4c7830aede574490aece3dcf
|