2
2
3
3
import collections
4
4
import json
5
- from enum import Enum
5
+ import platform
6
6
import sys
7
+ from enum import Enum
7
8
8
9
import click
9
10
@@ -20,9 +21,11 @@ class OutputFormat(Enum):
20
21
def print_json (data ):
21
22
print (json .dumps (data , sort_keys = True , indent = 2 ))
22
23
24
+
23
25
def log (* msgs ):
24
26
print (* msgs , file = sys .stderr )
25
27
28
+
26
29
class OrderedGroup (click .Group ):
27
30
def __init__ (self , name = None , commands = None , ** attrs ):
28
31
super (OrderedGroup , self ).__init__ (name , commands , ** attrs )
@@ -85,26 +88,26 @@ def cli(
85
88
):
86
89
"""The official QFieldCloud CLI tool. Allows interaction with the QFieldCloud server API.
87
90
88
- Environment:
91
+ Environment:
89
92
90
- Environment variables can be used instead of passing some common global options.
93
+ Environment variables can be used instead of passing some common global options.
91
94
92
- QFIELDCLOUD_API - QFieldCloud API endpoint URL
95
+ QFIELDCLOUD_API - QFieldCloud API endpoint URL
93
96
94
- QFIELDCLOUD_USERNAME - QFieldCloud username or email. Requires `QFIELDCLOUD_PASSWORD` to be set.
97
+ QFIELDCLOUD_USERNAME - QFieldCloud username or email. Requires `QFIELDCLOUD_PASSWORD` to be set.
95
98
96
- QFIELDCLOUD_PASSWORD - Password. Requires `QFIELDCLOUD_USERNAME` to be set.
99
+ QFIELDCLOUD_PASSWORD - Password. Requires `QFIELDCLOUD_USERNAME` to be set.
97
100
98
- QFIELDCLOUD_TOKEN - Token that can be used instead of passing username and password. It can be obtained by running `qfieldcloud-cli login`.
101
+ QFIELDCLOUD_TOKEN - Token that can be used instead of passing username and password. It can be obtained by running `qfieldcloud-cli login`.
99
102
100
- QFIELDCLOUD_VERIFY_SSL - When set to `0` has the same effect as passing `--no-verify-ssl`.
103
+ QFIELDCLOUD_VERIFY_SSL - When set to `0` has the same effect as passing `--no-verify-ssl`.
101
104
102
105
103
- Examples:
106
+ Examples:
104
107
105
- qfieldcloud-cli login user pass
108
+ qfieldcloud-cli login user pass
106
109
107
- qfieldcloud-cli -u user -p pass -U https://localhost/api/v1/ list-projects
110
+ qfieldcloud-cli -u user -p pass -U https://localhost/api/v1/ list-projects
108
111
"""
109
112
ctx .ensure_object (dict )
110
113
ctx .obj ["client" ] = sdk .Client (url , verify_ssl , token = token )
@@ -134,15 +137,18 @@ def login(ctx, username, password) -> None:
134
137
"Put the token in your in the environment using the following code, "
135
138
"so you do not need to write your username and password again:"
136
139
)
137
- log (f'export QFIELDCLOUD_TOKEN="{ user_data ["token" ]} "' )
140
+ if platform .system () == "Windows" :
141
+ log (f'set QFIELDCLOUD_TOKEN={ user_data ["token" ]} ' )
142
+ else :
143
+ log (f'export QFIELDCLOUD_TOKEN="{ user_data ["token" ]} "' )
138
144
139
145
140
146
@cli .command ()
141
147
@click .pass_context
142
148
def logout (ctx ):
143
149
"""Logout and expire the token."""
144
150
145
- log (f' Log out…' )
151
+ log (" Log out…" )
146
152
147
153
payload = ctx .obj ["client" ].logout ()
148
154
@@ -202,7 +208,11 @@ def list_files(ctx, project_id):
202
208
203
209
@cli .command ()
204
210
@click .argument ("name" )
205
- @click .option ("--owner" , "owner" , help = "Owner of the project. If omitted, the current user is the owner." )
211
+ @click .option (
212
+ "--owner" ,
213
+ "owner" ,
214
+ help = "Owner of the project. If omitted, the current user is the owner." ,
215
+ )
206
216
@click .option ("--description" , "description" , help = "Description of the project." )
207
217
@click .option (
208
218
"--is-public/--is-private" , "is_public" , help = "Mark the project as public."
@@ -298,13 +308,20 @@ def upload_files(ctx, project_id, project_path, filter_glob, throw_on_error):
298
308
help = "Download file even if it already exists locally. Default: False" ,
299
309
)
300
310
@click .pass_context
301
- def download_files (ctx , project_id , local_dir , filter_glob , throw_on_error , force_download ):
311
+ def download_files (
312
+ ctx , project_id , local_dir , filter_glob , throw_on_error , force_download
313
+ ):
302
314
"""Download QFieldCloud project files."""
303
315
304
316
log (f'Downloading project "{ project_id } " files to { local_dir } …' )
305
317
306
318
files = ctx .obj ["client" ].download_project (
307
- project_id , local_dir , filter_glob , throw_on_error , show_progress = True , force_download = force_download ,
319
+ project_id ,
320
+ local_dir ,
321
+ filter_glob ,
322
+ throw_on_error ,
323
+ show_progress = True ,
324
+ force_download = force_download ,
308
325
)
309
326
310
327
if ctx .obj ["format_json" ]:
@@ -321,9 +338,7 @@ def download_files(ctx, project_id, local_dir, filter_glob, throw_on_error, forc
321
338
log (f"Downloaded { count } file(s)." )
322
339
else :
323
340
if filter_glob :
324
- log (
325
- f"No files to download for project { project_id } at { filter_glob } "
326
- )
341
+ log (f"No files to download for project { project_id } at { filter_glob } " )
327
342
else :
328
343
log (f"No files to download for project { project_id } " )
329
344
@@ -346,9 +361,15 @@ def delete_files(ctx, project_id, paths, throw_on_error):
346
361
if ctx .obj ["format_json" ]:
347
362
print_json (paths_result )
348
363
364
+
349
365
@cli .command ()
350
366
@click .argument ("project_id" )
351
- @click .option ("--type" , "job_type" , type = sdk .JobTypes , help = "Job type. One of package, delta_apply or process_projectfile." )
367
+ @click .option (
368
+ "--type" ,
369
+ "job_type" ,
370
+ type = sdk .JobTypes ,
371
+ help = "Job type. One of package, delta_apply or process_projectfile." ,
372
+ )
352
373
@click .pass_context
353
374
def list_jobs (ctx , project_id , job_type ):
354
375
"""List project jobs."""
@@ -361,7 +382,9 @@ def list_jobs(ctx, project_id, job_type):
361
382
print_json (jobs )
362
383
else :
363
384
for job in jobs :
364
- log (f'Job "{ job ["id" ]} " of project "{ project_id } " is of type "{ job ["type" ]} " and has status "{ job ["status" ]} ".' )
385
+ log (
386
+ f'Job "{ job ["id" ]} " of project "{ project_id } " is of type "{ job ["type" ]} " and has status "{ job ["status" ]} ".'
387
+ )
365
388
366
389
367
390
@cli .command ()
@@ -383,7 +406,9 @@ def job_trigger(ctx, project_id, job_type, force):
383
406
if ctx .obj ["format_json" ]:
384
407
print_json (status )
385
408
else :
386
- log (f'Job of type "{ job_type } " triggered for project "{ project_id } ": { status ["id" ]} ' )
409
+ log (
410
+ f'Job of type "{ job_type } " triggered for project "{ project_id } ": { status ["id" ]} '
411
+ )
387
412
388
413
389
414
@cli .command ()
@@ -417,7 +442,7 @@ def package_latest(ctx, project_id):
417
442
else :
418
443
log (f'Packaging status for { project_id } : { status ["status" ]} ' )
419
444
if status ["layers" ] is None :
420
- if status ["status" ] == ' failed' :
445
+ if status ["status" ] == " failed" :
421
446
log ("Packaging have never been triggered on this project. Please run:" )
422
447
log (f"qfieldcloud-cli job-trigger { project_id } package" )
423
448
return
@@ -450,13 +475,20 @@ def package_latest(ctx, project_id):
450
475
help = "Download file even if it already exists locally. Default: False" ,
451
476
)
452
477
@click .pass_context
453
- def package_download (ctx , project_id , local_dir , filter_glob , throw_on_error , force_download ):
478
+ def package_download (
479
+ ctx , project_id , local_dir , filter_glob , throw_on_error , force_download
480
+ ):
454
481
"""Download packaged QFieldCloud project files."""
455
482
456
483
log (f'Downloading the latest project "{ project_id } " package files to { local_dir } …' )
457
484
458
485
files = ctx .obj ["client" ].package_download (
459
- project_id , local_dir , filter_glob , throw_on_error , show_progress = True , force_download = force_download ,
486
+ project_id ,
487
+ local_dir ,
488
+ filter_glob ,
489
+ throw_on_error ,
490
+ show_progress = True ,
491
+ force_download = force_download ,
460
492
)
461
493
462
494
if ctx .obj ["format_json" ]:
0 commit comments