accli 2.0.0rc4__tar.gz → 2.0.1__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.
- {accli-2.0.0rc4 → accli-2.0.1}/PKG-INFO +1 -1
- {accli-2.0.0rc4 → accli-2.0.1}/accli/AcceleratorTaskDispatcher.py +2 -2
- {accli-2.0.0rc4 → accli-2.0.1}/accli/_version.py +1 -1
- {accli-2.0.0rc4 → accli-2.0.1}/accli/cli.py +15 -84
- {accli-2.0.0rc4 → accli-2.0.1}/accli/setup-nfs.ps1 +18 -0
- accli-2.0.1/accli/token.py +194 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli.egg-info/PKG-INFO +1 -1
- accli-2.0.0rc4/accli/token.py +0 -115
- {accli-2.0.0rc4 → accli-2.0.1}/LICENSE +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/README.md +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli/AcceleratorJobProjectService.py +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli/AcceleratorTerminalCliProjectService.py +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli/CsvRegionalTimeseriesValidator.py +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli/__init__.py +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli/__main__.py +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli/cleanup-nfs.ps1 +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli/common.py +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli/gui.py +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli/mount_downloader.py +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli.egg-info/SOURCES.txt +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli.egg-info/dependency_links.txt +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli.egg-info/entry_points.txt +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli.egg-info/requires.txt +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/accli.egg-info/top_level.txt +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/pyproject.toml +0 -0
- {accli-2.0.0rc4 → accli-2.0.1}/setup.cfg +0 -0
|
@@ -11,7 +11,7 @@ from pydantic import BaseModel, model_validator
|
|
|
11
11
|
from accli.AcceleratorTerminalCliProjectService import AcceleratorTerminalCliProjectService
|
|
12
12
|
from accli.token import (
|
|
13
13
|
get_token, get_server_url,
|
|
14
|
-
get_project_slug
|
|
14
|
+
get_project_slug, exchange_refresh_token
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
ACCLI_DEBUG = os.environ.get('ACCLI_DEBUG', False)
|
|
@@ -65,9 +65,9 @@ def copy_tree(src, dst):
|
|
|
65
65
|
|
|
66
66
|
@lru_cache(maxsize=None)
|
|
67
67
|
def push_folder_job(directory):
|
|
68
|
-
access_token = get_token()
|
|
69
68
|
server_url = get_server_url()
|
|
70
69
|
project_slug = get_project_slug()
|
|
70
|
+
_, access_token, _ = exchange_refresh_token(project_slug)
|
|
71
71
|
|
|
72
72
|
term_cli_project_service = AcceleratorTerminalCliProjectService(
|
|
73
73
|
user_token=access_token,
|
|
@@ -15,7 +15,7 @@ from typing import List
|
|
|
15
15
|
|
|
16
16
|
from accli.AcceleratorTerminalCliProjectService import AcceleratorTerminalCliProjectService
|
|
17
17
|
from accli.CsvRegionalTimeseriesValidator import CsvRegionalTimeseriesValidator
|
|
18
|
-
from accli.token import save_token_details, get_token, get_server_url, set_project_slug, get_project_slug, get_db_path
|
|
18
|
+
from accli.token import save_token_details, get_token, get_server_url, set_project_slug, get_project_slug, get_db_path, exchange_refresh_token
|
|
19
19
|
from rich import print
|
|
20
20
|
from rich.progress import Progress, TextColumn, BarColumn, TaskProgressColumn, TimeElapsedColumn
|
|
21
21
|
from typing_extensions import Annotated
|
|
@@ -182,84 +182,7 @@ def compute_sha256(filepath: str) -> str:
|
|
|
182
182
|
h.update(chunk)
|
|
183
183
|
return h.hexdigest()
|
|
184
184
|
|
|
185
|
-
import threading
|
|
186
185
|
|
|
187
|
-
_token_lock = threading.Lock()
|
|
188
|
-
_cached_cas_token = None
|
|
189
|
-
_cached_expires_at = 0
|
|
190
|
-
_cached_access_token = None
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
def exchange_refresh_token(project_slug: str) -> tuple[str, str, int]:
|
|
194
|
-
"""
|
|
195
|
-
Exchanges the stored refresh token for a short-lived access token
|
|
196
|
-
and a new rotated refresh token. Updates the local TinyDB token cache.
|
|
197
|
-
Returns (cas_token, access_token, expires_at).
|
|
198
|
-
"""
|
|
199
|
-
import time
|
|
200
|
-
from tinydb import TinyDB
|
|
201
|
-
from accli.token import get_db_path, save_token_details
|
|
202
|
-
|
|
203
|
-
global _cached_cas_token, _cached_expires_at, _cached_access_token
|
|
204
|
-
|
|
205
|
-
# 1. Fast-path check: Reuse valid in-memory cache if still fresh (> 5 mins remaining)
|
|
206
|
-
# and matches the requested project slug prefix.
|
|
207
|
-
now = int(time.time())
|
|
208
|
-
if _cached_cas_token and _cached_access_token and (_cached_expires_at - now > 300):
|
|
209
|
-
expected_prefix = f"xet_session_prj_{project_slug}_"
|
|
210
|
-
if _cached_cas_token.startswith(expected_prefix):
|
|
211
|
-
return _cached_cas_token, _cached_access_token, _cached_expires_at
|
|
212
|
-
|
|
213
|
-
# 2. Block/lock to serialize requests and avoid rotation race conditions (RTR invalidation)
|
|
214
|
-
with _token_lock:
|
|
215
|
-
# Re-check cache inside the lock (double-checked locking pattern)
|
|
216
|
-
now = int(time.time())
|
|
217
|
-
if _cached_cas_token and _cached_access_token and (_cached_expires_at - now > 300):
|
|
218
|
-
expected_prefix = f"xet_session_prj_{project_slug}_"
|
|
219
|
-
if _cached_cas_token.startswith(expected_prefix):
|
|
220
|
-
return _cached_cas_token, _cached_access_token, _cached_expires_at
|
|
221
|
-
|
|
222
|
-
db_path = get_db_path()
|
|
223
|
-
db = TinyDB(db_path)
|
|
224
|
-
item = next(iter(db), {})
|
|
225
|
-
refresh_token = item.get('token')
|
|
226
|
-
server_url = item.get('server_url', "https://accelerator.iiasa.ac.at")
|
|
227
|
-
webcli_url = item.get('webcli_url', "https://accelerator.iiasa.ac.at")
|
|
228
|
-
|
|
229
|
-
if not refresh_token:
|
|
230
|
-
print("[bold red]ERROR: No token found. Please run 'accli login' first.[/bold red]")
|
|
231
|
-
raise typer.Exit(1)
|
|
232
|
-
|
|
233
|
-
refresh_endpoint = f"{server_url.rstrip('/')}/api/v1/oauth/device/access-token/"
|
|
234
|
-
|
|
235
|
-
try:
|
|
236
|
-
response = requests.post(
|
|
237
|
-
refresh_endpoint,
|
|
238
|
-
json={"refresh_token": refresh_token},
|
|
239
|
-
verify=(not ACCLI_DEBUG)
|
|
240
|
-
)
|
|
241
|
-
response.raise_for_status()
|
|
242
|
-
data = response.json()
|
|
243
|
-
|
|
244
|
-
access_token = data["access_token"]
|
|
245
|
-
new_refresh_token = data["refresh_token"]
|
|
246
|
-
|
|
247
|
-
# Save rotated refresh token back to local TinyDB
|
|
248
|
-
save_token_details(new_refresh_token, server_url, webcli_url)
|
|
249
|
-
|
|
250
|
-
cas_token = f"xet_session_prj_{project_slug}_{access_token}"
|
|
251
|
-
# Expire slightly before the 1-hour limit (e.g. 50 minutes)
|
|
252
|
-
expires_at = int(time.time()) + 3000
|
|
253
|
-
|
|
254
|
-
# Populate in-memory cache
|
|
255
|
-
_cached_cas_token = cas_token
|
|
256
|
-
_cached_access_token = access_token
|
|
257
|
-
_cached_expires_at = expires_at
|
|
258
|
-
|
|
259
|
-
return cas_token, access_token, expires_at
|
|
260
|
-
except Exception as e:
|
|
261
|
-
print(f"[bold red]ERROR: Failed to authenticate/exchange refresh token: {e}[/bold red]")
|
|
262
|
-
raise typer.Exit(1)
|
|
263
186
|
|
|
264
187
|
|
|
265
188
|
@app.command()
|
|
@@ -409,12 +332,16 @@ def copy(
|
|
|
409
332
|
refresh_url = f"{server_url.rstrip('/')}/api/v1/oauth/device/cas-token/"
|
|
410
333
|
refresh_headers = {"Authorization": f"Bearer {cas_token}"}
|
|
411
334
|
|
|
412
|
-
|
|
335
|
+
import sys
|
|
336
|
+
columns = [
|
|
413
337
|
TextColumn("[progress.description]{task.description}"),
|
|
414
|
-
BarColumn(),
|
|
415
338
|
TaskProgressColumn(),
|
|
416
339
|
TimeElapsedColumn(),
|
|
417
|
-
|
|
340
|
+
]
|
|
341
|
+
if sys.stdout.isatty():
|
|
342
|
+
columns.insert(1, BarColumn())
|
|
343
|
+
|
|
344
|
+
with Progress(*columns) as progress:
|
|
418
345
|
total_size = sum(item[2] for item in files_to_download)
|
|
419
346
|
overall_task = progress.add_task("[green]Total Download Progress...", total=total_size)
|
|
420
347
|
|
|
@@ -548,12 +475,16 @@ def copy(
|
|
|
548
475
|
refresh_url = f"{server_url.rstrip('/')}/api/v1/oauth/device/cas-token/"
|
|
549
476
|
refresh_headers = {"Authorization": f"Bearer {cas_token}"}
|
|
550
477
|
|
|
551
|
-
|
|
478
|
+
import sys
|
|
479
|
+
columns = [
|
|
552
480
|
TextColumn("[progress.description]{task.description}"),
|
|
553
|
-
BarColumn(),
|
|
554
481
|
TaskProgressColumn(),
|
|
555
482
|
TimeElapsedColumn(),
|
|
556
|
-
|
|
483
|
+
]
|
|
484
|
+
if sys.stdout.isatty():
|
|
485
|
+
columns.insert(1, BarColumn())
|
|
486
|
+
|
|
487
|
+
with Progress(*columns) as progress:
|
|
557
488
|
total_size = sum(p.stat().st_size for p in local_paths)
|
|
558
489
|
overall_task = progress.add_task("[green]Total Upload Progress...", total=total_size)
|
|
559
490
|
|
|
@@ -35,6 +35,17 @@ if (-not $NfsAlreadyEnabled) {
|
|
|
35
35
|
Write-Host "[OK] Client for NFS features already enabled." -ForegroundColor Green
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
# 1.5 Configure Client for NFS (NfsClnt) service startup type to Manual
|
|
39
|
+
# This prevents NFS Client from starting automatically on Windows boot, avoiding startup delays/hangs.
|
|
40
|
+
# The service will be started on-demand when accli mounts a drive.
|
|
41
|
+
Write-Host "Configuring Client for NFS (NfsClnt) service startup type to Manual..." -ForegroundColor Cyan
|
|
42
|
+
if (Get-Service -Name "NfsClnt" -ErrorAction SilentlyContinue) {
|
|
43
|
+
Set-Service -Name "NfsClnt" -StartupType Manual -ErrorAction SilentlyContinue
|
|
44
|
+
Write-Host "[OK] NfsClnt service startup type configured to Manual." -ForegroundColor Green
|
|
45
|
+
} else {
|
|
46
|
+
Write-Warning "Client for NFS service (NfsClnt) not found. Could not configure startup type."
|
|
47
|
+
}
|
|
48
|
+
|
|
38
49
|
# 2. Add Registry value for Linked Connections
|
|
39
50
|
# Allows mapped network drives to be shared between elevated and standard sessions under the same user log-in.
|
|
40
51
|
if (-not $RegAlreadyEnabled) {
|
|
@@ -108,6 +119,13 @@ if ($cfg.skip_auto_mount) {
|
|
|
108
119
|
$env:HF_MOUNT_SKIP_AUTO_MOUNT = "1"
|
|
109
120
|
}
|
|
110
121
|
|
|
122
|
+
# Ensure NfsClnt service is started before attempting mount
|
|
123
|
+
try {
|
|
124
|
+
if ((Get-Service -Name "NfsClnt" -ErrorAction SilentlyContinue).Status -ne 'Running') {
|
|
125
|
+
Start-Service -Name "NfsClnt" -ErrorAction SilentlyContinue
|
|
126
|
+
}
|
|
127
|
+
} catch {}
|
|
128
|
+
|
|
111
129
|
# Construct arguments
|
|
112
130
|
$mountArgs = @(
|
|
113
131
|
"--token-file", $cfg.db_path,
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import threading
|
|
3
|
+
import time
|
|
4
|
+
import requests
|
|
5
|
+
import typer
|
|
6
|
+
from tinydb import TinyDB
|
|
7
|
+
|
|
8
|
+
ACCLI_DEBUG = os.environ.get('ACCLI_DEBUG', False)
|
|
9
|
+
|
|
10
|
+
_token_lock = threading.Lock()
|
|
11
|
+
_cached_cas_token = None
|
|
12
|
+
_cached_expires_at = 0
|
|
13
|
+
_cached_access_token = None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_db_path():
|
|
17
|
+
sudo_user = os.environ.get("SUDO_USER")
|
|
18
|
+
pkexec_uid = os.environ.get("PKEXEC_UID")
|
|
19
|
+
|
|
20
|
+
if (sudo_user or pkexec_uid) and os.name != "nt":
|
|
21
|
+
try:
|
|
22
|
+
import pwd
|
|
23
|
+
if pkexec_uid:
|
|
24
|
+
home = pwd.getpwuid(int(pkexec_uid)).pw_dir
|
|
25
|
+
else:
|
|
26
|
+
home = pwd.getpwnam(sudo_user).pw_dir
|
|
27
|
+
except Exception:
|
|
28
|
+
home = os.path.expanduser("~")
|
|
29
|
+
else:
|
|
30
|
+
home = os.path.expanduser("~")
|
|
31
|
+
|
|
32
|
+
token_directory = f"{home}/.accli"
|
|
33
|
+
|
|
34
|
+
if not os.path.exists(token_directory):
|
|
35
|
+
os.makedirs(token_directory)
|
|
36
|
+
|
|
37
|
+
return f"{token_directory}/data.json"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def save_token_details(token, server_url, webcli_url):
|
|
41
|
+
db_path = get_db_path()
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
os.remove(db_path)
|
|
45
|
+
except OSError:
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
db = TinyDB(db_path)
|
|
49
|
+
db.insert({
|
|
50
|
+
'token': token,
|
|
51
|
+
'server_url': server_url,
|
|
52
|
+
'webcli_url': webcli_url
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def get_token():
|
|
57
|
+
db_path = get_db_path()
|
|
58
|
+
|
|
59
|
+
db = TinyDB(db_path)
|
|
60
|
+
|
|
61
|
+
for item in db:
|
|
62
|
+
token = item.get('token')
|
|
63
|
+
if token:
|
|
64
|
+
break
|
|
65
|
+
|
|
66
|
+
if not token:
|
|
67
|
+
print("Token does not exists. Please login.")
|
|
68
|
+
return token
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def exchange_refresh_token(project_slug: str) -> tuple[str, str, int]:
|
|
72
|
+
"""
|
|
73
|
+
Exchanges the stored refresh token for a short-lived access token
|
|
74
|
+
and a new rotated refresh token. Updates the local TinyDB token cache.
|
|
75
|
+
Returns (cas_token, access_token, expires_at).
|
|
76
|
+
"""
|
|
77
|
+
global _cached_cas_token, _cached_expires_at, _cached_access_token
|
|
78
|
+
|
|
79
|
+
# 1. Fast-path check: Reuse valid in-memory cache if still fresh (> 5 mins remaining)
|
|
80
|
+
# and matches the requested project slug prefix.
|
|
81
|
+
now = int(time.time())
|
|
82
|
+
if _cached_cas_token and _cached_access_token and (_cached_expires_at - now > 300):
|
|
83
|
+
expected_prefix = f"xet_session_prj_{project_slug}_"
|
|
84
|
+
if _cached_cas_token.startswith(expected_prefix):
|
|
85
|
+
return _cached_cas_token, _cached_access_token, _cached_expires_at
|
|
86
|
+
|
|
87
|
+
# 2. Block/lock to serialize requests and avoid rotation race conditions (RTR invalidation)
|
|
88
|
+
with _token_lock:
|
|
89
|
+
# Re-check cache inside the lock (double-checked locking pattern)
|
|
90
|
+
now = int(time.time())
|
|
91
|
+
if _cached_cas_token and _cached_access_token and (_cached_expires_at - now > 300):
|
|
92
|
+
expected_prefix = f"xet_session_prj_{project_slug}_"
|
|
93
|
+
if _cached_cas_token.startswith(expected_prefix):
|
|
94
|
+
return _cached_cas_token, _cached_access_token, _cached_expires_at
|
|
95
|
+
|
|
96
|
+
db_path = get_db_path()
|
|
97
|
+
db = TinyDB(db_path)
|
|
98
|
+
item = next(iter(db), {})
|
|
99
|
+
refresh_token = item.get('token')
|
|
100
|
+
server_url = item.get('server_url', "https://accelerator.iiasa.ac.at")
|
|
101
|
+
webcli_url = item.get('webcli_url', "https://accelerator.iiasa.ac.at")
|
|
102
|
+
|
|
103
|
+
if not refresh_token:
|
|
104
|
+
print("[bold red]ERROR: No token found. Please run 'accli login' first.[/bold red]")
|
|
105
|
+
raise typer.Exit(1)
|
|
106
|
+
|
|
107
|
+
refresh_endpoint = f"{server_url.rstrip('/')}/api/v1/oauth/device/access-token/"
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
response = requests.post(
|
|
111
|
+
refresh_endpoint,
|
|
112
|
+
json={"refresh_token": refresh_token},
|
|
113
|
+
verify=(not ACCLI_DEBUG)
|
|
114
|
+
)
|
|
115
|
+
response.raise_for_status()
|
|
116
|
+
data = response.json()
|
|
117
|
+
|
|
118
|
+
access_token = data["access_token"]
|
|
119
|
+
new_refresh_token = data["refresh_token"]
|
|
120
|
+
|
|
121
|
+
# Save rotated refresh token back to local TinyDB
|
|
122
|
+
save_token_details(new_refresh_token, server_url, webcli_url)
|
|
123
|
+
|
|
124
|
+
cas_token = f"xet_session_prj_{project_slug}_{access_token}"
|
|
125
|
+
# Expire slightly before the 1-hour limit (e.g. 50 minutes)
|
|
126
|
+
expires_at = int(time.time()) + 3000
|
|
127
|
+
|
|
128
|
+
# Populate in-memory cache
|
|
129
|
+
_cached_cas_token = cas_token
|
|
130
|
+
_cached_access_token = access_token
|
|
131
|
+
_cached_expires_at = expires_at
|
|
132
|
+
|
|
133
|
+
return cas_token, access_token, expires_at
|
|
134
|
+
except Exception as e:
|
|
135
|
+
print(f"[bold red]ERROR: Failed to authenticate/exchange refresh token: {e}[/bold red]")
|
|
136
|
+
raise typer.Exit(1)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def get_github_app_token():
|
|
140
|
+
db_path = get_db_path()
|
|
141
|
+
|
|
142
|
+
db = TinyDB(db_path)
|
|
143
|
+
|
|
144
|
+
for item in db:
|
|
145
|
+
token = item.get('github_app_token')
|
|
146
|
+
if token:
|
|
147
|
+
break
|
|
148
|
+
|
|
149
|
+
if not token:
|
|
150
|
+
print("Github app token does not exists.")
|
|
151
|
+
return token
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def set_github_app_token(github_app_token):
|
|
155
|
+
db_path = get_db_path()
|
|
156
|
+
db = TinyDB(db_path)
|
|
157
|
+
db.update({'github_app_token': github_app_token}, doc_ids=[1])
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def set_project_slug(project_slug):
|
|
161
|
+
db_path = get_db_path()
|
|
162
|
+
db = TinyDB(db_path)
|
|
163
|
+
db.update({'project_slug': project_slug}, doc_ids=[1])
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def get_project_slug():
|
|
167
|
+
db_path = get_db_path()
|
|
168
|
+
|
|
169
|
+
db = TinyDB(db_path)
|
|
170
|
+
|
|
171
|
+
for item in db:
|
|
172
|
+
project_slug = item.get('project_slug')
|
|
173
|
+
if project_slug:
|
|
174
|
+
break
|
|
175
|
+
|
|
176
|
+
if not project_slug:
|
|
177
|
+
print("project slug was not set.")
|
|
178
|
+
return project_slug
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def get_server_url():
|
|
182
|
+
db_path = get_db_path()
|
|
183
|
+
|
|
184
|
+
db = TinyDB(db_path)
|
|
185
|
+
|
|
186
|
+
for item in db:
|
|
187
|
+
server_url = item.get('server_url')
|
|
188
|
+
if server_url:
|
|
189
|
+
break
|
|
190
|
+
|
|
191
|
+
if not server_url:
|
|
192
|
+
print("Server url does not exists. Please login.")
|
|
193
|
+
return server_url
|
|
194
|
+
|
accli-2.0.0rc4/accli/token.py
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
|
-
from tinydb import TinyDB
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def get_db_path():
|
|
7
|
-
sudo_user = os.environ.get("SUDO_USER")
|
|
8
|
-
pkexec_uid = os.environ.get("PKEXEC_UID")
|
|
9
|
-
|
|
10
|
-
if (sudo_user or pkexec_uid) and os.name != "nt":
|
|
11
|
-
try:
|
|
12
|
-
import pwd
|
|
13
|
-
if pkexec_uid:
|
|
14
|
-
home = pwd.getpwuid(int(pkexec_uid)).pw_dir
|
|
15
|
-
else:
|
|
16
|
-
home = pwd.getpwnam(sudo_user).pw_dir
|
|
17
|
-
except Exception:
|
|
18
|
-
home = os.path.expanduser("~")
|
|
19
|
-
else:
|
|
20
|
-
home = os.path.expanduser("~")
|
|
21
|
-
|
|
22
|
-
token_directory = f"{home}/.accli"
|
|
23
|
-
|
|
24
|
-
if not os.path.exists(token_directory):
|
|
25
|
-
os.makedirs(token_directory)
|
|
26
|
-
|
|
27
|
-
return f"{token_directory}/data.json"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def save_token_details(token, server_url, webcli_url):
|
|
31
|
-
db_path = get_db_path()
|
|
32
|
-
|
|
33
|
-
try:
|
|
34
|
-
os.remove(db_path)
|
|
35
|
-
except OSError:
|
|
36
|
-
pass
|
|
37
|
-
|
|
38
|
-
db = TinyDB(db_path)
|
|
39
|
-
db.insert({
|
|
40
|
-
'token': token,
|
|
41
|
-
'server_url': server_url,
|
|
42
|
-
'webcli_url': webcli_url
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def get_token():
|
|
47
|
-
db_path = get_db_path()
|
|
48
|
-
|
|
49
|
-
db = TinyDB(db_path)
|
|
50
|
-
|
|
51
|
-
for item in db:
|
|
52
|
-
token = item.get('token')
|
|
53
|
-
if token:
|
|
54
|
-
break
|
|
55
|
-
|
|
56
|
-
if not token:
|
|
57
|
-
print("Token does not exists. Please login.")
|
|
58
|
-
return token
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def get_github_app_token():
|
|
62
|
-
db_path = get_db_path()
|
|
63
|
-
|
|
64
|
-
db = TinyDB(db_path)
|
|
65
|
-
|
|
66
|
-
for item in db:
|
|
67
|
-
token = item.get('github_app_token')
|
|
68
|
-
if token:
|
|
69
|
-
break
|
|
70
|
-
|
|
71
|
-
if not token:
|
|
72
|
-
print("Github app token does not exists.")
|
|
73
|
-
return token
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def set_github_app_token(github_app_token):
|
|
77
|
-
db_path = get_db_path()
|
|
78
|
-
db = TinyDB(db_path)
|
|
79
|
-
db.update({'github_app_token': github_app_token}, doc_ids=[1])
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def set_project_slug(project_slug):
|
|
83
|
-
db_path = get_db_path()
|
|
84
|
-
db = TinyDB(db_path)
|
|
85
|
-
db.update({'project_slug': project_slug}, doc_ids=[1])
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def get_project_slug():
|
|
89
|
-
db_path = get_db_path()
|
|
90
|
-
|
|
91
|
-
db = TinyDB(db_path)
|
|
92
|
-
|
|
93
|
-
for item in db:
|
|
94
|
-
project_slug = item.get('project_slug')
|
|
95
|
-
if project_slug:
|
|
96
|
-
break
|
|
97
|
-
|
|
98
|
-
if not project_slug:
|
|
99
|
-
print("project slug was not set.")
|
|
100
|
-
return project_slug
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def get_server_url():
|
|
104
|
-
db_path = get_db_path()
|
|
105
|
-
|
|
106
|
-
db = TinyDB(db_path)
|
|
107
|
-
|
|
108
|
-
for item in db:
|
|
109
|
-
server_url = item.get('server_url')
|
|
110
|
-
if server_url:
|
|
111
|
-
break
|
|
112
|
-
|
|
113
|
-
if not server_url:
|
|
114
|
-
print("Server url does not exists. Please login.")
|
|
115
|
-
return server_url
|
|
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
|
|
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
|