tempspace-cli 1.1.1__tar.gz → 1.2.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.
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/PKG-INFO +1 -2
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/cli/tempspace.py +59 -39
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/pyproject.toml +1 -2
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/tempspace_cli.egg-info/PKG-INFO +1 -2
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/tempspace_cli.egg-info/requires.txt +0 -1
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/README.md +0 -0
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/cli/__init__.py +0 -0
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/setup.cfg +0 -0
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/tempspace_cli.egg-info/SOURCES.txt +0 -0
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/tempspace_cli.egg-info/dependency_links.txt +0 -0
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/tempspace_cli.egg-info/entry_points.txt +0 -0
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/tempspace_cli.egg-info/top_level.txt +0 -0
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/tests/test_cli.py +0 -0
- {tempspace_cli-1.1.1 → tempspace_cli-1.2.0}/tests/test_main.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tempspace-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: A command-line tool for uploading files to Tempspace.
|
|
5
5
|
Author-email: Tempspace <mcbplay1@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -9,7 +9,6 @@ Classifier: Operating System :: OS Independent
|
|
|
9
9
|
Requires-Python: >=3.7
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
Requires-Dist: requests==2.31.0
|
|
12
|
-
Requires-Dist: tqdm==4.66.1
|
|
13
12
|
Requires-Dist: requests-toolbelt==1.0.0
|
|
14
13
|
Requires-Dist: rich==13.7.1
|
|
15
14
|
Requires-Dist: qrcode==8.2
|
|
@@ -4,7 +4,6 @@ import os
|
|
|
4
4
|
import sys
|
|
5
5
|
import hashlib
|
|
6
6
|
import multiprocessing
|
|
7
|
-
from tqdm import tqdm
|
|
8
7
|
from requests_toolbelt.multipart.encoder import MultipartEncoder, MultipartEncoderMonitor
|
|
9
8
|
import math
|
|
10
9
|
from rich.console import Console
|
|
@@ -13,6 +12,9 @@ from rich.table import Table
|
|
|
13
12
|
from rich import box
|
|
14
13
|
import qrcode
|
|
15
14
|
from rich.prompt import Prompt, Confirm
|
|
15
|
+
from rich.progress import Progress, BarColumn, TextColumn, TransferSpeedColumn, TimeRemainingColumn
|
|
16
|
+
from rich.console import Group
|
|
17
|
+
from rich.live import Live
|
|
16
18
|
|
|
17
19
|
# Default configuration
|
|
18
20
|
DEFAULT_SERVER_URL = "https://tempspace.fly.dev/"
|
|
@@ -41,18 +43,6 @@ def parse_time(time_str: str) -> int:
|
|
|
41
43
|
except ValueError:
|
|
42
44
|
return None
|
|
43
45
|
|
|
44
|
-
def calculate_file_hash(filepath: str) -> str:
|
|
45
|
-
"""Calculate the SHA256 hash of a file in chunks."""
|
|
46
|
-
sha256_hash = hashlib.sha256()
|
|
47
|
-
try:
|
|
48
|
-
with open(filepath, "rb") as f:
|
|
49
|
-
for byte_block in iter(lambda: f.read(CHUNK_SIZE), b""):
|
|
50
|
-
sha256_hash.update(byte_block)
|
|
51
|
-
return sha256_hash.hexdigest()
|
|
52
|
-
except IOError as e:
|
|
53
|
-
print(f"Error reading file for hashing: {e}", file=sys.stderr)
|
|
54
|
-
sys.exit(1)
|
|
55
|
-
|
|
56
46
|
def format_size(size_bytes: int) -> str:
|
|
57
47
|
"""Converts a size in bytes to a human-readable format."""
|
|
58
48
|
if size_bytes == 0:
|
|
@@ -117,47 +107,77 @@ def main():
|
|
|
117
107
|
console.print(table)
|
|
118
108
|
|
|
119
109
|
|
|
120
|
-
# --- Hashing ---
|
|
121
|
-
console.print("[cyan]Calculating file hash...[/]")
|
|
122
|
-
client_hash = calculate_file_hash(args.filepath)
|
|
123
|
-
console.print(f" [cyan]- Hash:[/] {client_hash}")
|
|
124
|
-
|
|
125
110
|
# --- Prepare Upload ---
|
|
126
|
-
upload_url = f"{args.url.rstrip('/')}
|
|
111
|
+
upload_url = f"{args.url.rstrip('/')}"
|
|
127
112
|
filename = os.path.basename(args.filepath)
|
|
128
113
|
file_size = os.path.getsize(args.filepath)
|
|
129
114
|
|
|
130
|
-
|
|
131
|
-
'hours': str(hours),
|
|
132
|
-
'one_time': str(args.one_time).lower(),
|
|
133
|
-
'client_hash': client_hash,
|
|
134
|
-
'file': (filename, open(args.filepath, 'rb'), 'application/octet-stream')
|
|
135
|
-
}
|
|
136
|
-
if args.password:
|
|
137
|
-
fields['password'] = args.password
|
|
138
|
-
|
|
139
|
-
encoder = MultipartEncoder(fields=fields)
|
|
115
|
+
# --- Chunked Upload ---
|
|
140
116
|
response = None
|
|
141
|
-
|
|
142
117
|
try:
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
118
|
+
# 1. Initiate Upload
|
|
119
|
+
initiate_response = requests.post(f"{upload_url}/upload/initiate")
|
|
120
|
+
initiate_response.raise_for_status()
|
|
121
|
+
upload_id = initiate_response.json()['upload_id']
|
|
122
|
+
|
|
123
|
+
# 2. Upload Chunks
|
|
124
|
+
progress = Progress(
|
|
125
|
+
TextColumn("[bold blue]{task.description}", justify="right"),
|
|
126
|
+
BarColumn(bar_width=None),
|
|
127
|
+
"[progress.percentage]{task.percentage:>3.1f}%", "•",
|
|
128
|
+
TransferSpeedColumn(), "•",
|
|
129
|
+
TimeRemainingColumn(),
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
with Live(Panel(progress, title="[cyan]Uploading[/cyan]", border_style="cyan", title_align="left")) as live:
|
|
133
|
+
task_id = progress.add_task(filename, total=file_size)
|
|
134
|
+
with open(args.filepath, 'rb') as f:
|
|
135
|
+
chunk_number = 0
|
|
136
|
+
while chunk := f.read(CHUNK_SIZE):
|
|
137
|
+
chunk_number += 1
|
|
138
|
+
chunk_data = {
|
|
139
|
+
'upload_id': upload_id,
|
|
140
|
+
'chunk_number': str(chunk_number)
|
|
141
|
+
}
|
|
142
|
+
files = {'file': (f'chunk_{chunk_number}', chunk, 'application/octet-stream')}
|
|
143
|
+
|
|
144
|
+
chunk_response = requests.post(
|
|
145
|
+
f"{upload_url}/upload/chunk",
|
|
146
|
+
data=chunk_data,
|
|
147
|
+
files=files
|
|
148
|
+
)
|
|
149
|
+
chunk_response.raise_for_status()
|
|
150
|
+
progress.update(task_id, advance=len(chunk))
|
|
151
|
+
|
|
152
|
+
# 3. Finalize Upload
|
|
153
|
+
console.print(Panel("[bold green]Finalizing upload...[/bold green]", border_style="green"))
|
|
154
|
+
finalize_data = {
|
|
155
|
+
'upload_id': upload_id,
|
|
156
|
+
'filename': filename,
|
|
157
|
+
'hours': str(hours),
|
|
158
|
+
'one_time': str(args.one_time).lower(),
|
|
159
|
+
}
|
|
160
|
+
if args.password:
|
|
161
|
+
finalize_data['password'] = args.password
|
|
162
|
+
|
|
163
|
+
response = requests.post(f"{upload_url}/upload/finalize", data=finalize_data)
|
|
164
|
+
response.raise_for_status()
|
|
147
165
|
|
|
148
166
|
except FileNotFoundError:
|
|
149
167
|
console.print(Panel(f"[bold red]Error:[/] The file '{args.filepath}' was not found.", title="[bold red]Error[/bold red]", border_style="red"))
|
|
150
168
|
sys.exit(1)
|
|
151
169
|
except requests.exceptions.RequestException as e:
|
|
152
|
-
|
|
170
|
+
error_message = str(e)
|
|
171
|
+
if e.response:
|
|
172
|
+
try:
|
|
173
|
+
error_message = e.response.json().get('detail', e.response.text)
|
|
174
|
+
except:
|
|
175
|
+
error_message = e.response.text
|
|
176
|
+
console.print(Panel(f"[bold red]An error occurred:[/] {error_message}", title="[bold red]Error[/bold red]", border_style="red"))
|
|
153
177
|
sys.exit(1)
|
|
154
178
|
except Exception as e:
|
|
155
179
|
console.print(Panel(f"[bold red]An unexpected error occurred:[/] {e}", title="[bold red]Error[/bold red]", border_style="red"))
|
|
156
180
|
sys.exit(1)
|
|
157
|
-
finally:
|
|
158
|
-
# Ensure the file handle is closed
|
|
159
|
-
if 'file' in fields and not fields['file'][1].closed:
|
|
160
|
-
fields['file'][1].close()
|
|
161
181
|
|
|
162
182
|
# --- Handle Response ---
|
|
163
183
|
if response is not None:
|
|
@@ -7,7 +7,7 @@ packages = ["cli"]
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "tempspace-cli"
|
|
10
|
-
version = "1.
|
|
10
|
+
version = "1.2.0"
|
|
11
11
|
authors = [
|
|
12
12
|
{ name="Tempspace", email="mcbplay1@gmail.com" },
|
|
13
13
|
]
|
|
@@ -21,7 +21,6 @@ classifiers = [
|
|
|
21
21
|
]
|
|
22
22
|
dependencies = [
|
|
23
23
|
"requests==2.31.0",
|
|
24
|
-
"tqdm==4.66.1",
|
|
25
24
|
"requests-toolbelt==1.0.0",
|
|
26
25
|
"rich==13.7.1",
|
|
27
26
|
"qrcode==8.2",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tempspace-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: A command-line tool for uploading files to Tempspace.
|
|
5
5
|
Author-email: Tempspace <mcbplay1@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -9,7 +9,6 @@ Classifier: Operating System :: OS Independent
|
|
|
9
9
|
Requires-Python: >=3.7
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
Requires-Dist: requests==2.31.0
|
|
12
|
-
Requires-Dist: tqdm==4.66.1
|
|
13
12
|
Requires-Dist: requests-toolbelt==1.0.0
|
|
14
13
|
Requires-Dist: rich==13.7.1
|
|
15
14
|
Requires-Dist: qrcode==8.2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|