RemoteRF 2.2.2__py3-none-any.whl → 2.2.4__py3-none-any.whl
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.
- remoterf/core/acc_login.py +2 -1
- remoterf/core/app.py +16 -3
- remoterf/deployment/homes.py +14 -0
- remoterf/remoterf_cli.py +48 -6
- {remoterf-2.2.2.dist-info → remoterf-2.2.4.dist-info}/METADATA +1 -1
- {remoterf-2.2.2.dist-info → remoterf-2.2.4.dist-info}/RECORD +10 -10
- {remoterf-2.2.2.dist-info → remoterf-2.2.4.dist-info}/WHEEL +0 -0
- {remoterf-2.2.2.dist-info → remoterf-2.2.4.dist-info}/entry_points.txt +0 -0
- {remoterf-2.2.2.dist-info → remoterf-2.2.4.dist-info}/licenses/LICENSE +0 -0
- {remoterf-2.2.2.dist-info → remoterf-2.2.4.dist-info}/top_level.txt +0 -0
remoterf/core/acc_login.py
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
15
15
|
|
|
16
16
|
def main(*, register=False, enrollment_code=None, server_label=None, show_banner=True,
|
|
17
|
-
home=None, route=None):
|
|
17
|
+
home=None, route=None, username=None):
|
|
18
18
|
from .app import run
|
|
19
19
|
return run(
|
|
20
20
|
register=register,
|
|
@@ -23,4 +23,5 @@ def main(*, register=False, enrollment_code=None, server_label=None, show_banner
|
|
|
23
23
|
show_banner=show_banner,
|
|
24
24
|
home=home,
|
|
25
25
|
route=route,
|
|
26
|
+
username=username,
|
|
26
27
|
)
|
remoterf/core/app.py
CHANGED
|
@@ -116,6 +116,8 @@ def _password_confirmation(*, enforce_policy=False):
|
|
|
116
116
|
|
|
117
117
|
# The code typed at `remoterf -r`, used once for this registration.
|
|
118
118
|
pending_enrollment_code = None
|
|
119
|
+
# A username already given (`name@lab` at `-l`): the login asks only the password.
|
|
120
|
+
pending_username = None
|
|
119
121
|
# The saved home this shell is attached to (None on a bare direct profile).
|
|
120
122
|
home_name = None
|
|
121
123
|
# The route it was reached over (None on a bare direct profile or an HTTPS home).
|
|
@@ -207,6 +209,9 @@ def _account_command(command):
|
|
|
207
209
|
account.email = _ask('Email') if policy['email_required'] else ''
|
|
208
210
|
if not account.create_user():
|
|
209
211
|
raise AccountBackendError('Registration failed')
|
|
212
|
+
if account.is_https_home:
|
|
213
|
+
from ..deployment import homes
|
|
214
|
+
printf(f"Log in from anywhere as {account.username}@{homes.GLOBAL_ACCOUNTS}", Sty.GRAY)
|
|
210
215
|
except BaseException:
|
|
211
216
|
# The code was fine; only the details failed. Keep it for the retry.
|
|
212
217
|
pending_enrollment_code = account.enrollment_code or None
|
|
@@ -249,7 +254,14 @@ def _account_command(command):
|
|
|
249
254
|
return False
|
|
250
255
|
if command in ('l', 'login'):
|
|
251
256
|
printf(f"Login to {_home_name()}", (Sty.BOLD, Sty.BLUE))
|
|
252
|
-
|
|
257
|
+
global pending_username
|
|
258
|
+
from ..deployment import homes
|
|
259
|
+
typed = pending_username or _ask('Username or Email' if account.is_https_home else 'Username')
|
|
260
|
+
pending_username = None
|
|
261
|
+
# `ethan@ucla` typed at ucla is `ethan` there.
|
|
262
|
+
name, where = homes.split_account(typed)
|
|
263
|
+
here = homes.GLOBAL_ACCOUNTS if account.is_https_home else home_name
|
|
264
|
+
account.username = name if where == here else typed
|
|
253
265
|
account.password = _ask('Password (Hidden)', hidden=True)
|
|
254
266
|
ok = bool(account.login_user(remember=not account.is_https_home))
|
|
255
267
|
if ok:
|
|
@@ -1585,8 +1597,9 @@ def interactive_reserve_next_days_auto():
|
|
|
1585
1597
|
|
|
1586
1598
|
|
|
1587
1599
|
def run(backend=None, *, register=False, enrollment_code=None, server_label=None,
|
|
1588
|
-
show_banner=True, home=None, route=None):
|
|
1589
|
-
global account, session, server_addr, pending_enrollment_code, home_name, current_route
|
|
1600
|
+
show_banner=True, home=None, route=None, username=None):
|
|
1601
|
+
global account, session, server_addr, pending_enrollment_code, home_name, current_route, pending_username
|
|
1602
|
+
pending_username = username
|
|
1590
1603
|
home_name = home
|
|
1591
1604
|
current_route = route
|
|
1592
1605
|
from ..deployment.backend import selected_backend
|
remoterf/deployment/homes.py
CHANGED
|
@@ -268,6 +268,20 @@ def connect(name: str) -> dict:
|
|
|
268
268
|
return route
|
|
269
269
|
|
|
270
270
|
|
|
271
|
+
# An account is `name@<deployment>`; Global's own accounts are `name@global`.
|
|
272
|
+
GLOBAL_ACCOUNTS = "global"
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def split_account(text: str) -> tuple[str, str | None]:
|
|
276
|
+
"""`ethan@ucla` -> ("ethan", "ucla"). A bare name, or an email (a dot
|
|
277
|
+
after the @; deployment names never have one), names no deployment."""
|
|
278
|
+
text = text.strip()
|
|
279
|
+
name, at, where = text.rpartition("@")
|
|
280
|
+
if not at or not name or not where or "." in where:
|
|
281
|
+
return text, None
|
|
282
|
+
return name, where.lower()
|
|
283
|
+
|
|
284
|
+
|
|
271
285
|
def register_home(host: str) -> tuple[str, dict, dict]:
|
|
272
286
|
"""Learn a deployment from its code, save it, and connect to it."""
|
|
273
287
|
document = discover(host)
|
remoterf/remoterf_cli.py
CHANGED
|
@@ -150,7 +150,7 @@ def print_help() -> None:
|
|
|
150
150
|
printf(" remoterf -h | --help", Sty.CYAN, " Show this help", Sty.DEFAULT)
|
|
151
151
|
print()
|
|
152
152
|
printf("Commands:", (Sty.BOLD, Sty.MAGENTA))
|
|
153
|
-
printf(" remoterf -l | --login [target]", Sty.CYAN, " Login: last used, 'global',
|
|
153
|
+
printf(" remoterf -l | --login [target]", Sty.CYAN, " Login: last used, 'global', a home name, or an account (ethan@ucla)", Sty.DEFAULT)
|
|
154
154
|
printf(" remoterf -r | --register [global]", Sty.CYAN, " Register with an enrollment code (or a RemoteRF Global account)", Sty.DEFAULT)
|
|
155
155
|
printf(" remoterf homes", Sty.CYAN, " List saved deployment homes", Sty.DEFAULT)
|
|
156
156
|
printf(" remoterf -v | --version", Sty.CYAN, " Print version", Sty.DEFAULT)
|
|
@@ -171,6 +171,7 @@ def print_help() -> None:
|
|
|
171
171
|
printf(" remoterf --login", Sty.GREEN)
|
|
172
172
|
printf(" remoterf --login ucla", Sty.GREEN)
|
|
173
173
|
printf(" remoterf --login global", Sty.GREEN)
|
|
174
|
+
printf(" remoterf --login ethan@ucla", Sty.GREEN)
|
|
174
175
|
printf(" remoterf homes", Sty.GREEN)
|
|
175
176
|
printf(" remoterf --version", Sty.GREEN)
|
|
176
177
|
printf(" remoterf --config --addr 203.0.113.10:12321", Sty.GREEN)
|
|
@@ -180,7 +181,8 @@ def print_help() -> None:
|
|
|
180
181
|
|
|
181
182
|
def _account_shell(*, register: bool, enrollment_code: str | None = None,
|
|
182
183
|
server_label: str | None = None, show_banner: bool = True,
|
|
183
|
-
home: str | None = None, route: dict | None = None
|
|
184
|
+
home: str | None = None, route: dict | None = None,
|
|
185
|
+
username: str | None = None) -> int:
|
|
184
186
|
ok, _ = _ensure_config_present()
|
|
185
187
|
if not ok:
|
|
186
188
|
_print_server_unavailable()
|
|
@@ -198,6 +200,7 @@ def _account_shell(*, register: bool, enrollment_code: str | None = None,
|
|
|
198
200
|
show_banner=show_banner,
|
|
199
201
|
home=home,
|
|
200
202
|
route=route,
|
|
203
|
+
username=username,
|
|
201
204
|
)
|
|
202
205
|
or 0
|
|
203
206
|
)
|
|
@@ -212,7 +215,7 @@ def _global_origin() -> str:
|
|
|
212
215
|
return os.getenv('REMOTERF_GLOBAL_ORIGIN', 'https://global.remoterf.net')
|
|
213
216
|
|
|
214
217
|
|
|
215
|
-
def _use_global(*, register: bool, show_banner: bool = True) -> int:
|
|
218
|
+
def _use_global(*, register: bool, show_banner: bool = True, username: str | None = None) -> int:
|
|
216
219
|
"""Register or log in with the RemoteRF Global identity itself.
|
|
217
220
|
|
|
218
221
|
A Global-native account is complete on its own: it needs no deployment
|
|
@@ -238,7 +241,7 @@ def _use_global(*, register: bool, show_banner: bool = True) -> int:
|
|
|
238
241
|
except (RuntimeError, ValueError) as exc:
|
|
239
242
|
print(f'Could not reach RemoteRF Global: {exc}')
|
|
240
243
|
return 2
|
|
241
|
-
return _account_shell(register=register, show_banner=show_banner)
|
|
244
|
+
return _account_shell(register=register, show_banner=show_banner, username=username)
|
|
242
245
|
|
|
243
246
|
|
|
244
247
|
@contextmanager
|
|
@@ -293,7 +296,8 @@ def _reason(exc: BaseException) -> str:
|
|
|
293
296
|
return str(exc)
|
|
294
297
|
|
|
295
298
|
|
|
296
|
-
def _use_home(name: str, *, register: bool, enrollment_code: str | None = None
|
|
299
|
+
def _use_home(name: str, *, register: bool, enrollment_code: str | None = None,
|
|
300
|
+
username: str | None = None) -> int:
|
|
297
301
|
from remoterf.deployment import homes
|
|
298
302
|
|
|
299
303
|
try:
|
|
@@ -309,6 +313,7 @@ def _use_home(name: str, *, register: bool, enrollment_code: str | None = None)
|
|
|
309
313
|
server_label=f'{name} ({_route_label(route)})',
|
|
310
314
|
home=name,
|
|
311
315
|
route={**route, 'home': home},
|
|
316
|
+
username=username,
|
|
312
317
|
)
|
|
313
318
|
|
|
314
319
|
|
|
@@ -382,6 +387,8 @@ def _login(target: str | None) -> int:
|
|
|
382
387
|
if not require_tos_for_login():
|
|
383
388
|
return 1
|
|
384
389
|
homes.migrate_legacy_target()
|
|
390
|
+
if target is not None and '@' in target:
|
|
391
|
+
return _login_as(target)
|
|
385
392
|
if target is None:
|
|
386
393
|
last = homes.last_target()
|
|
387
394
|
saved = sorted(homes.homes())
|
|
@@ -397,7 +404,7 @@ def _login(target: str | None) -> int:
|
|
|
397
404
|
# Nothing saved. A legacy address in .env still logs in there;
|
|
398
405
|
# a fresh install has nothing to log in to, so `-l` is `-r`.
|
|
399
406
|
if not _ensure_config_present()[0]:
|
|
400
|
-
return
|
|
407
|
+
return _login_by_username()
|
|
401
408
|
return _account_shell(register=False)
|
|
402
409
|
if target == 'global':
|
|
403
410
|
# Global's address is built in, so a fresh install can log in to an
|
|
@@ -409,6 +416,41 @@ def _login(target: str | None) -> int:
|
|
|
409
416
|
return _use_home(target, register=False)
|
|
410
417
|
|
|
411
418
|
|
|
419
|
+
def _login_by_username() -> int:
|
|
420
|
+
"""A fresh install: an account says where it lives (`ethan@ucla`), so
|
|
421
|
+
asking for it is enough. Enter registers, as `-l` here always did."""
|
|
422
|
+
try:
|
|
423
|
+
name = input('Account, e.g. ethan@ucla (Enter to register): ').strip()
|
|
424
|
+
except (EOFError, KeyboardInterrupt):
|
|
425
|
+
print()
|
|
426
|
+
return 1
|
|
427
|
+
if not name:
|
|
428
|
+
return _register()
|
|
429
|
+
return _login_as(name)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
def _login_as(account: str) -> int:
|
|
433
|
+
"""Log in to `name@lab` at that lab; a bare name or an email is Global."""
|
|
434
|
+
from remoterf.deployment import homes
|
|
435
|
+
|
|
436
|
+
name, lab = homes.split_account(account)
|
|
437
|
+
if lab is None or lab == homes.GLOBAL_ACCOUNTS:
|
|
438
|
+
return _use_global(register=False, username=name)
|
|
439
|
+
if lab in homes.homes():
|
|
440
|
+
return _use_home(lab, register=False, username=name)
|
|
441
|
+
host = f'{lab}.{homes.GLOBAL_DOMAIN}'
|
|
442
|
+
try:
|
|
443
|
+
with _working(f"Looking up {host}…"):
|
|
444
|
+
lab, home, route = homes.register_home(host)
|
|
445
|
+
except (RuntimeError, ValueError) as exc:
|
|
446
|
+
printf(f'Could not reach {host}: {_reason(exc)}', Sty.WARNING)
|
|
447
|
+
return 2
|
|
448
|
+
return _account_shell(
|
|
449
|
+
register=False, server_label=f'{lab} ({_route_label(route)})',
|
|
450
|
+
home=lab, route={**route, 'home': home}, username=name,
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
|
|
412
454
|
def _print_pick_a_target() -> int:
|
|
413
455
|
_print_homes()
|
|
414
456
|
printf('Choose one: ', Sty.GRAY, 'remoterf --login <name>', Sty.CYAN)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: remoterf
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.4
|
|
4
4
|
Summary: A python API to remotely access signal centric hardware. Client-side only! Courtesy of Wireless Lab @ UCLA & Prof. Ian Roberts.
|
|
5
5
|
Author-email: Ethan Ge <ethoGalaxy@gmail.com>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
remoterf.py,sha256=3fQ4zYeDo4Q8n5stT0H5ol8t2njckfY-FDuTZ2yEx5w,1843
|
|
2
2
|
remoterf/__init__.py,sha256=-1h_xQjiE66oiWRO-vnLGJ4smpgUNhFuV-ZreW9_tD4,667
|
|
3
|
-
remoterf/remoterf_cli.py,sha256=
|
|
3
|
+
remoterf/remoterf_cli.py,sha256=VG-56Ncs2r8HMWPUa0wg98rhbIcW-z_aHqkaFnzCNcI,23682
|
|
4
4
|
remoterf/version.py,sha256=NWzcPOAdd567IvC8ei1yyPdeS7w0kt99oKwL6oWAQSc,850
|
|
5
5
|
remoterf/common/__init__.py,sha256=ey1IjkAaXFL1sZBnBwuWVlHhA_n0bu_uxgkDV_KOxYg,708
|
|
6
6
|
remoterf/common/tos_notice.txt,sha256=fUHXV6U9uhZDvVs8BcRi4kWbU1PeU9mkxML0n5DDQp8,334
|
|
@@ -22,8 +22,8 @@ remoterf/config/__init__.py,sha256=-1h_xQjiE66oiWRO-vnLGJ4smpgUNhFuV-ZreW9_tD4,6
|
|
|
22
22
|
remoterf/config/cert_fetcher.py,sha256=_m4CiYxJPTckDrdynwUjwnehD_gd6yZoly5etfT83JY,6986
|
|
23
23
|
remoterf/config/config.py,sha256=xuwYXS7zLgG77nSEn6br4X0vXK7Z2rlmBKedyDVI7Fc,9353
|
|
24
24
|
remoterf/core/__init__.py,sha256=1E9ARnxVICp4uCpGNQT3Fb-jD9TvUYbJmctuUqPy8hU,1206
|
|
25
|
-
remoterf/core/acc_login.py,sha256=
|
|
26
|
-
remoterf/core/app.py,sha256=
|
|
25
|
+
remoterf/core/acc_login.py,sha256=i-uKtN2LPaGbPy0ngUzR1fIXWTxSMUwyDHF3ProEKz4,1052
|
|
26
|
+
remoterf/core/app.py,sha256=ILWi3RLr9svP7D2nMnOntoXLvp--bv0Q3UI5uYpDHp0,74087
|
|
27
27
|
remoterf/core/banner_note.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
28
|
remoterf/core/direct_path.py,sha256=PeqagybrFESHO9-LKwR8F8t14T0dJTZHIlRxepTQtoo,32291
|
|
29
29
|
remoterf/core/dynamic_v2_transport.py,sha256=rR0Mfjh3Kcz4QJKJen2gsUNjYtHy22PfsZg2KLDIptI,22052
|
|
@@ -34,7 +34,7 @@ remoterf/core/v2_errors.py,sha256=Xmuta24cfQEy4FGG7HZk7B9hD5g4pGT5Hz8Eguy42lU,29
|
|
|
34
34
|
remoterf/deployment/__init__.py,sha256=aEl9z32KMUBfRRm6Ho0-fM-VUtiKIRq4bQBU2_u29-c,69
|
|
35
35
|
remoterf/deployment/backend.py,sha256=FNj3wYk0NSpt4LZnBNwU4OHSCFGLNGYmmuSuFZ6rIcQ,16155
|
|
36
36
|
remoterf/deployment/direct.py,sha256=uD72drR0Z21cNG7xSZUeDiQ80OSspFLj9BS_vj9Dapk,1048
|
|
37
|
-
remoterf/deployment/homes.py,sha256=
|
|
37
|
+
remoterf/deployment/homes.py,sha256=HhfKuKw_Ul540rLVy2Bu_txxeP_3OqWXv8z14_Y3_v4,12852
|
|
38
38
|
remoterf/deployment/http.py,sha256=ePwOyRrkwNiciIOImqMiS1VoJCw51j6MeLEcaMavgh0,4564
|
|
39
39
|
remoterf/deployment/state.py,sha256=rXHEMf-kJP1sYCJn-VD84ZNalkYUaNAiYaoaVu4uo3U,6541
|
|
40
40
|
remoterf/drivers/__init__.py,sha256=DXjon8E0R1X27fDQDy6IrwzqTFwrT6-suC5VSDXUP8Y,1250
|
|
@@ -59,9 +59,9 @@ remoterf/drivers/ti_mmwave/ti_mmwave_remote.py,sha256=hYUJUtPz3yRgGsmXzwo95ZYnvJ
|
|
|
59
59
|
remoterf/drivers/usrp/__init__.py,sha256=y79nl50_4dV9-AI3cfDptOAWeR58fAaihHObqJI9HJM,780
|
|
60
60
|
remoterf/drivers/usrp/usrp_remote.py,sha256=hBh_CmGOAoEkkdQQ8uPFAsBA6LVeZsPSlpPGgo1c7sM,115018
|
|
61
61
|
remoterf/drivers/usrp/usrp_remote.pyi,sha256=MG7rMJdjyT0hLLoJmnS1emDQjgepWz695GbFED3v-T4,11810
|
|
62
|
-
remoterf-2.2.
|
|
63
|
-
remoterf-2.2.
|
|
64
|
-
remoterf-2.2.
|
|
65
|
-
remoterf-2.2.
|
|
66
|
-
remoterf-2.2.
|
|
67
|
-
remoterf-2.2.
|
|
62
|
+
remoterf-2.2.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
63
|
+
remoterf-2.2.4.dist-info/METADATA,sha256=RP019PUTxHjFKaxn7v7q5hORP5RBF7OQM3cxZJQMv1c,12778
|
|
64
|
+
remoterf-2.2.4.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
65
|
+
remoterf-2.2.4.dist-info/entry_points.txt,sha256=83-XNRsKpeQK8A0rzkPfjwb4zF4m3l3cCRhxWm_Er0w,56
|
|
66
|
+
remoterf-2.2.4.dist-info/top_level.txt,sha256=BUtCT3KOhL-A4r6WL4RslW53rsZflOhHwq77RODYhlk,9
|
|
67
|
+
remoterf-2.2.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|