rbrowser 0.1.6__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.
Files changed (118) hide show
  1. rbrowser-0.1.6.dist-info/METADATA +123 -0
  2. rbrowser-0.1.6.dist-info/RECORD +118 -0
  3. rbrowser-0.1.6.dist-info/WHEEL +5 -0
  4. rbrowser-0.1.6.dist-info/entry_points.txt +2 -0
  5. rbrowser-0.1.6.dist-info/top_level.txt +1 -0
  6. rbrowser_cli/__init__.py +3 -0
  7. rbrowser_cli/cli.py +143 -0
  8. rbrowser_cli/frontend/assets/fonts/desyrel/desyrel.png +0 -0
  9. rbrowser_cli/frontend/assets/fonts/desyrel/desyrel.xml +1923 -0
  10. rbrowser_cli/frontend/assets/fonts/inter/Inter-16.png +0 -0
  11. rbrowser_cli/frontend/assets/fonts/inter/Inter-16.xml +1 -0
  12. rbrowser_cli/frontend/assets/fonts/inter/Inter-72.png +0 -0
  13. rbrowser_cli/frontend/assets/fonts/inter/Inter-72.xml +1 -0
  14. rbrowser_cli/frontend/assets/fonts/inter/Inter-ExtraLightBETA.png +0 -0
  15. rbrowser_cli/frontend/assets/fonts/inter/Inter-ExtraLightBETA.xml +1 -0
  16. rbrowser_cli/frontend/assets/fonts/inter/Inter-Light-18.png +0 -0
  17. rbrowser_cli/frontend/assets/fonts/inter/Inter-Light-18.xml +1 -0
  18. rbrowser_cli/frontend/assets/fonts/inter/Inter-Light-64.png +0 -0
  19. rbrowser_cli/frontend/assets/fonts/inter/Inter-Light-64.xml +1 -0
  20. rbrowser_cli/frontend/assets/fonts/inter/Inter-LightBETA-64.png +0 -0
  21. rbrowser_cli/frontend/assets/fonts/inter/Inter-LightBETA-64.xml +1 -0
  22. rbrowser_cli/frontend/assets/fonts/inter/Inter-LightBETA.png +0 -0
  23. rbrowser_cli/frontend/assets/fonts/inter/Inter-LightBETA.xml +1 -0
  24. rbrowser_cli/frontend/assets/fonts/inter/Inter-Regular.json +2183 -0
  25. rbrowser_cli/frontend/assets/fonts/inter/Inter-Regular.png +0 -0
  26. rbrowser_cli/frontend/assets/fonts/inter/Inter-Regular.xml +101 -0
  27. rbrowser_cli/frontend/assets/fonts/inter/Inter-SemiBold-64.png +0 -0
  28. rbrowser_cli/frontend/assets/fonts/inter/Inter-SemiBold-64.xml +1 -0
  29. rbrowser_cli/frontend/assets/fonts/inter/inter.xml +793 -0
  30. rbrowser_cli/frontend/assets/fonts/inter/inter_0.png +0 -0
  31. rbrowser_cli/frontend/assets/fonts/inter_regular/Inter-Regular.json +2183 -0
  32. rbrowser_cli/frontend/assets/fonts/inter_regular/Inter-Regular.ttf +0 -0
  33. rbrowser_cli/frontend/assets/fonts/inter_regular/font.0.png +0 -0
  34. rbrowser_cli/frontend/assets/fonts/inter_regular/font.1.png +0 -0
  35. rbrowser_cli/frontend/assets/fonts/inter_regular/font.png +0 -0
  36. rbrowser_cli/frontend/assets/fonts/opensans/OpenSans-Regular.json +1472 -0
  37. rbrowser_cli/frontend/assets/fonts/opensans/OpenSans-Regular.ttf +0 -0
  38. rbrowser_cli/frontend/assets/fonts/opensans/font.png +0 -0
  39. rbrowser_cli/frontend/assets/g3d/genome.g3d +0 -0
  40. rbrowser_cli/frontend/assets/icon/settings.svg +1 -0
  41. rbrowser_cli/frontend/assets/textures/arrow_down.png +0 -0
  42. rbrowser_cli/frontend/assets/textures/arrow_up.png +0 -0
  43. rbrowser_cli/frontend/assets/textures/ball_gray.png +0 -0
  44. rbrowser_cli/frontend/assets/textures/ball_gray3.png +0 -0
  45. rbrowser_cli/frontend/assets/textures/ball_gray_10x10.png +0 -0
  46. rbrowser_cli/frontend/assets/textures/ball_gray_5x5.png +0 -0
  47. rbrowser_cli/frontend/assets/textures/ball_white_100.png +0 -0
  48. rbrowser_cli/frontend/assets/textures/ball_white_20.png +0 -0
  49. rbrowser_cli/frontend/assets/textures/ball_white_40.png +0 -0
  50. rbrowser_cli/frontend/assets/textures/base_A.png +0 -0
  51. rbrowser_cli/frontend/assets/textures/base_C.png +0 -0
  52. rbrowser_cli/frontend/assets/textures/base_G.png +0 -0
  53. rbrowser_cli/frontend/assets/textures/base_T.png +0 -0
  54. rbrowser_cli/frontend/assets/textures/base_U.png +0 -0
  55. rbrowser_cli/frontend/assets/textures/circle_100.png +0 -0
  56. rbrowser_cli/frontend/assets/textures/circle_black_100.png +0 -0
  57. rbrowser_cli/frontend/assets/textures/circle_red.png +0 -0
  58. rbrowser_cli/frontend/assets/textures/circle_white_100.png +0 -0
  59. rbrowser_cli/frontend/assets/textures/diamond copy.png +0 -0
  60. rbrowser_cli/frontend/assets/textures/diamond.png +0 -0
  61. rbrowser_cli/frontend/assets/textures/diamond2.png +0 -0
  62. rbrowser_cli/frontend/assets/textures/drop.png +0 -0
  63. rbrowser_cli/frontend/assets/textures/drop_line.png +0 -0
  64. rbrowser_cli/frontend/assets/textures/ele_gray.png +0 -0
  65. rbrowser_cli/frontend/assets/textures/ele_grays.png +0 -0
  66. rbrowser_cli/frontend/assets/textures/ele_green.png +0 -0
  67. rbrowser_cli/frontend/assets/textures/ele_ocean.png +0 -0
  68. rbrowser_cli/frontend/assets/textures/ele_red.png +0 -0
  69. rbrowser_cli/frontend/assets/textures/ele_sky.png +0 -0
  70. rbrowser_cli/frontend/assets/textures/ele_soft_gray.png +0 -0
  71. rbrowser_cli/frontend/assets/textures/ele_yellow.png +0 -0
  72. rbrowser_cli/frontend/assets/textures/texture.psd +0 -0
  73. rbrowser_cli/frontend/assets/textures/texture_ATCG.psd +0 -0
  74. rbrowser_cli/frontend/assets/textures/texture_circle_org.png +0 -0
  75. rbrowser_cli/frontend/assets/textures/texture_diamond.psd +0 -0
  76. rbrowser_cli/frontend/assets/textures/texture_grey_border_main.png +0 -0
  77. rbrowser_cli/frontend/assets/textures/texture_grey_main.png +0 -0
  78. rbrowser_cli/frontend/assets/textures/texture_grey_main.psd +0 -0
  79. rbrowser_cli/frontend/assets/textures/triangle.png +0 -0
  80. rbrowser_cli/frontend/favicon.ico +0 -0
  81. rbrowser_cli/frontend/index.html +49 -0
  82. rbrowser_cli/frontend/logo192.png +0 -0
  83. rbrowser_cli/frontend/logo512.png +0 -0
  84. rbrowser_cli/frontend/manifest.json +25 -0
  85. rbrowser_cli/frontend/robots.txt +3 -0
  86. rbrowser_cli/frontend/static/css/index.ArNRqnY1.css +1 -0
  87. rbrowser_cli/frontend/static/css/index.CroWzXsC.css +1 -0
  88. rbrowser_cli/frontend/static/css/index.DPMyIVYU.css +1 -0
  89. rbrowser_cli/frontend/static/js/AppstoreAddOutlined.D5ilOMxt.chunk.js +3 -0
  90. rbrowser_cli/frontend/static/js/CheckCircleRounded.DVZy-MCf.chunk.js +1 -0
  91. rbrowser_cli/frontend/static/js/ClearAllRounded.CUJRdVDQ.chunk.js +1 -0
  92. rbrowser_cli/frontend/static/js/ExpandMore.C46BDO5j.chunk.js +1 -0
  93. rbrowser_cli/frontend/static/js/Refresh.C83YUbTk.chunk.js +1 -0
  94. rbrowser_cli/frontend/static/js/d3-vendor.D2vplkPo.chunk.js +1 -0
  95. rbrowser_cli/frontend/static/js/datahub-data.BkMvslYe.chunk.js +1 -0
  96. rbrowser_cli/frontend/static/js/index.B36BqAW0.chunk.js +1 -0
  97. rbrowser_cli/frontend/static/js/index.B79vQDf2.chunk.js +1 -0
  98. rbrowser_cli/frontend/static/js/index.D1QXMsT8.chunk.js +1 -0
  99. rbrowser_cli/frontend/static/js/index.DICxSQgm.chunk.js +1 -0
  100. rbrowser_cli/frontend/static/js/index.DezPsQiY.chunk.js +1 -0
  101. rbrowser_cli/frontend/static/js/index.DhVVPnZF.chunk.js +1 -0
  102. rbrowser_cli/frontend/static/js/index.DpkFDdug.js +145 -0
  103. rbrowser_cli/frontend/static/js/index.JBr0C4Rc.chunk.js +1 -0
  104. rbrowser_cli/frontend/static/js/index.Lr6WmsZR.chunk.js +40 -0
  105. rbrowser_cli/frontend/static/js/index.Pv0g6RaM.chunk.js +1 -0
  106. rbrowser_cli/frontend/static/js/index.WaMjEOTD.chunk.js +31 -0
  107. rbrowser_cli/frontend/static/js/index.oG4Fdp8e.chunk.js +1 -0
  108. rbrowser_cli/frontend/static/js/index.pFX21XGS.chunk.js +1 -0
  109. rbrowser_cli/frontend/static/js/index.qnCfw2-y.chunk.js +1 -0
  110. rbrowser_cli/frontend/static/js/mui-vendor.C2wT3-V2.chunk.js +140 -0
  111. rbrowser_cli/frontend/static/js/pixi-vendor.DwNHHdM-.chunk.js +1 -0
  112. rbrowser_cli/frontend/static/js/react-vendor.C018e_IG.chunk.js +56 -0
  113. rbrowser_cli/frontend/static/js/redux-vendor.BYT4ly2K.chunk.js +11 -0
  114. rbrowser_cli/frontend/static/media/logo.BdaLZdU8.png +0 -0
  115. rbrowser_cli/output.py +91 -0
  116. rbrowser_cli/path_parser.py +57 -0
  117. rbrowser_cli/server_local.py +236 -0
  118. rbrowser_cli/server_ssh.py +280 -0
@@ -0,0 +1,123 @@
1
+ Metadata-Version: 2.4
2
+ Name: rbrowser
3
+ Version: 0.1.6
4
+ Summary: Launch RBrowser with a local or remote (SSH) directory as a file server
5
+ Author: RBrowser Team
6
+ License: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: click>=8.0
10
+ Requires-Dist: flask>=2.0
11
+ Requires-Dist: flask-cors>=4.0
12
+
13
+ # RBrowser CLI
14
+
15
+ Launch [RBrowser](https://rbrowser.org) with a local or remote (SSH) directory
16
+ as a file server backend. **The frontend UI is bundled inside the wheel** —
17
+ one `pip install` and you're ready to go (no Node.js, no extra build step).
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install rbrowser-cli
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ```bash
28
+ # Open current directory (UI served from http://localhost:<port>)
29
+ rbrowser open .
30
+
31
+ # Open a specific directory
32
+ rbrowser open /data/myproject
33
+
34
+ # Open a remote SSH directory (requires ssh-agent or key auth)
35
+ rbrowser open user@host:/data/myproject
36
+
37
+ # Use a custom port
38
+ rbrowser open . --port 8888
39
+
40
+ # Override the bundled UI with a hosted RBrowser
41
+ rbrowser open . --frontend https://rbrowser.org
42
+ ```
43
+
44
+ The CLI prints (and auto-opens) a URL like
45
+ `http://localhost:<port>/#/main?fileServerUrl=...`, which jumps the user
46
+ directly to the Main view's File Explorer panel — no home-page detour.
47
+
48
+ When run on a remote SSH host, the URL is printed as a Ctrl+Click hyperlink so
49
+ you can open it from your local terminal.
50
+
51
+ ---
52
+
53
+ ## Maintainer notes (release flow)
54
+
55
+ End users do **not** need to do this. To produce a wheel that ships the UI:
56
+
57
+ ```bash
58
+ # One-shot: install JS deps, build frontend, build sdist + wheel
59
+ node rbrowser-cli/scripts/build_release.mjs
60
+
61
+ # Skip the npm install (faster local iterations)
62
+ node rbrowser-cli/scripts/build_release.mjs --skip-install
63
+
64
+ # Or via npm:
65
+ npm run release:cli # full pipeline
66
+ npm run build:cli-wheel # skip-install variant
67
+
68
+ # Output is in rbrowser-cli/dist/ (sdist + wheel)
69
+ ```
70
+
71
+ ### Publishing to PyPI via GitHub Actions
72
+
73
+ The workflow [`.github/workflows/publish-rbrowser-cli.yml`](../.github/workflows/publish-rbrowser-cli.yml)
74
+ publishes a release to PyPI using **Trusted Publishing** (OIDC — no API
75
+ token in repo secrets). To set it up once:
76
+
77
+ 1. On <https://pypi.org/manage/account/publishing/>, add a _pending publisher_:
78
+ - PyPI project name: `rbrowser-cli`
79
+ - Owner: `typekey` · Repository: `rna-browser`
80
+ - Workflow: `publish-rbrowser-cli.yml`
81
+ - Environment: `pypi`
82
+ 2. In the GitHub repo Settings → Environments, create an environment named
83
+ `pypi` (optionally with a required reviewer).
84
+
85
+ Then to release:
86
+
87
+ ```bash
88
+ # One-liner: bump patch version, build, commit, tag, push.
89
+ # (PyPI is published automatically by the GitHub Action.)
90
+ npm run release:cli:patch # 0.1.0 -> 0.1.1
91
+ npm run release:cli:minor # 0.1.0 -> 0.2.0
92
+ npm run release:cli:major # 0.1.0 -> 1.0.0
93
+
94
+ # Or pick an explicit version (and add --push when ready):
95
+ node rbrowser-cli/scripts/release.mjs 0.2.3 --push
96
+
97
+ # Dry-run / inspect first; create the tag locally without pushing:
98
+ node rbrowser-cli/scripts/release.mjs patch # local tag only
99
+ node rbrowser-cli/scripts/release.mjs patch --dry-run # print, don't mutate
100
+ ```
101
+
102
+ What `release.mjs` does:
103
+
104
+ 1. Resolves the new version (explicit or `patch` / `minor` / `major` bump).
105
+ 2. Verifies the working tree is clean and on `main` (override with
106
+ `--allow-dirty` / `--branch=…`).
107
+ 3. Rewrites `pyproject.toml`'s version.
108
+ 4. Runs the full local build (skip with `--no-build`) so you can spot any
109
+ issue before the tag is pushed.
110
+ 5. Commits, creates the annotated tag `rbrowser-cli-vX.Y.Z`, and (with
111
+ `--push`) pushes both to `origin` — which fires the publish workflow.
112
+
113
+ Manual fallback (no script):
114
+
115
+ ```bash
116
+ # Update version in rbrowser-cli/pyproject.toml first.
117
+ git commit -am "chore(rbrowser-cli): release v0.1.1"
118
+ git tag rbrowser-cli-v0.1.1
119
+ git push origin main rbrowser-cli-v0.1.1
120
+ ```
121
+
122
+ `pyproject.toml` already declares `frontend/**/*` as `package-data`, so the
123
+ built UI is included in the wheel automatically.
@@ -0,0 +1,118 @@
1
+ rbrowser_cli/__init__.py,sha256=3xrOfIhiATUWy5OndOVg3x-mtkvjyWZPfID20AbwlIw,96
2
+ rbrowser_cli/cli.py,sha256=rZk7HtttegVT-PODCuZ0PQlLlg1HirS_33Rsuo-vEHE,4602
3
+ rbrowser_cli/output.py,sha256=pO1P1LxLUJYBSQSfhGS3434IIZFTSDlBwIeJKUCBov8,2650
4
+ rbrowser_cli/path_parser.py,sha256=X6Ih0ke_k8IDloOKfYtoD2aur9NwbCriZcUoQb2S83A,1637
5
+ rbrowser_cli/server_local.py,sha256=irehyCRRYrplD0bCZ5BAJbgZA-gpo2Plqjwm2ORMgoc,7708
6
+ rbrowser_cli/server_ssh.py,sha256=vNi3ab63joYUGDbpseysBKnMxn3WGDzKTxRsQKHvM-Q,10196
7
+ rbrowser_cli/frontend/favicon.ico,sha256=6ICwAuKpPi_JOvgE3zKO88-OHHXyUL8E_kkHDpLkcgk,15406
8
+ rbrowser_cli/frontend/index.html,sha256=Sm0BbWZuKI0hYMg9f4B86zF1JqmONT6_KTDdTqwLL0Y,2050
9
+ rbrowser_cli/frontend/logo192.png,sha256=uXQVPYoVnmR1Va8zIaWR7lYCZAxtgI-aHLcPYW-l9i4,27833
10
+ rbrowser_cli/frontend/logo512.png,sha256=P6Kodjqv2L_zxxXqyqBVzfXWvSHTU4Et4Bz4NAp6Nm0,170907
11
+ rbrowser_cli/frontend/manifest.json,sha256=ULPYw5A68_eNhxuUVXqxT045yhkurKPSz6hjyGcnmhQ,492
12
+ rbrowser_cli/frontend/robots.txt,sha256=kNJLw79pisHhc3OVAimMzKcq3x9WT6sF9IS4xI0crdI,67
13
+ rbrowser_cli/frontend/assets/fonts/desyrel/desyrel.png,sha256=K9ER-UMITbERhzrfG9200YzAXIjDvjAomtRSDcj64W0,310362
14
+ rbrowser_cli/frontend/assets/fonts/desyrel/desyrel.xml,sha256=nM9dPfjPahBBFsEsgTQ6Ole7Q-PrDL21TGMM-LVLpw4,112219
15
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-16.png,sha256=mSVRv_vl6npUcZ1DfAnzJdf4jONm5jBbHxHtDfeAx4E,7135
16
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-16.xml,sha256=q56ULkysqmFo5N8iqRiX1Qtm5we_Rnjc2OmCNhnh8Kc,10206
17
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-72.png,sha256=IGhVI2wFqWuySxdiIcCkfjyATCWFzJK6x9-RporqoLY,54482
18
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-72.xml,sha256=vssN_ja8Wn6nZtpOmM5tpyJ9zpWNn5Z3aGtKoETDGEc,10471
19
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-ExtraLightBETA.png,sha256=gJhzCfiJL1Vj4w_B1G0x1bYKNqz02UAXRIQLm0FjbEQ,55024
20
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-ExtraLightBETA.xml,sha256=5_00ZqUpW1lmlmC5rtCQmvuyehNJ3n-HgPkNyUPtfJk,40751
21
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-Light-18.png,sha256=NqE7IFzFue9p3YT49mCrKzk6W2AVkAtf-koaOi05Fxo,20320
22
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-Light-18.xml,sha256=ETVx-3Gczvxeranswx1gg5PGtwhyO6vRXE9-qOqVSvA,33672
23
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-Light-64.png,sha256=UQ53jU5DJ9u5f70TOnT5t-1SJaO346NmBKKtfzNXG5s,110597
24
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-Light-64.xml,sha256=ocfkM0PQZs0rufyYhOspVb-12Wjj4yNkEuFSVX9MJeI,40755
25
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-LightBETA-64.png,sha256=1NJav3l_PN9pQZ2mUs9E__f78e39W6ksPlVscMfg-yw,48050
26
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-LightBETA-64.xml,sha256=1p4QppskJ39ZpYicIYDt8r-9W-Jihiaf6l16Ft8IcP0,40748
27
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-LightBETA.png,sha256=GQ5BFXa4RWdm6MDpw4Wc8b1494Q8j91eqho-I6DU7zA,8113
28
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-LightBETA.xml,sha256=qMANyPz2EQSxZe69roCSPC2-_Gu7mOZM2R_5YQcUkew,32368
29
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-Regular.json,sha256=nG1jv2FIHwCRR2KQH6JiwXZxif8Cf_t42poIE7giH_8,46231
30
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-Regular.png,sha256=wudtvrs6on3NRW4N3JFaM0ZosWOxZxQFEpBlWG2V7gs,54557
31
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-Regular.xml,sha256=HzBT1NNBu00XC0jD8pttYn75Vc97fDMZ93_nO7U59cw,11342
32
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-SemiBold-64.png,sha256=7dAE-jMveS5T4KKOOe_DuuDCFhe9CzaDS2PzAPw224I,49856
33
+ rbrowser_cli/frontend/assets/fonts/inter/Inter-SemiBold-64.xml,sha256=67-V3GPaHnhTLkwKFsLe6KSx8KGy-ZXJ8iS7YrrPlcc,41016
34
+ rbrowser_cli/frontend/assets/fonts/inter/inter.xml,sha256=itVz72w-9rR6SJ8mtmFuCwjLTa2NlWHkmM7hzDOTaLk,46720
35
+ rbrowser_cli/frontend/assets/fonts/inter/inter_0.png,sha256=OXD2Kn_LHUOFr2l8-1FmjROq-tDPCOHwzlMCYP-YDBQ,7736
36
+ rbrowser_cli/frontend/assets/fonts/inter_regular/Inter-Regular.json,sha256=WzvP-YZ5FhQmPzJapRzeTggpY_hfLYADurpOLS3Z7wo,46263
37
+ rbrowser_cli/frontend/assets/fonts/inter_regular/Inter-Regular.ttf,sha256=QNaS_OGI5EceKzy6k3vpZ4ePYxrT67vc1YdofH6-DII,411640
38
+ rbrowser_cli/frontend/assets/fonts/inter_regular/font.0.png,sha256=sOVhK4Ork85m4qJziULPmTpyj7aHNXEhPgDogk7fTuQ,231987
39
+ rbrowser_cli/frontend/assets/fonts/inter_regular/font.1.png,sha256=glPcOj3HsVifsmWOv5ys44R-h_AjpxQnIVtFXJz-IOk,98541
40
+ rbrowser_cli/frontend/assets/fonts/inter_regular/font.png,sha256=FdhSaUO_dLQyuWP9q1LM86kyWAFl_4UpWr7yF_0XgmI,338241
41
+ rbrowser_cli/frontend/assets/fonts/opensans/OpenSans-Regular.json,sha256=mejpdlaZdk_WfnlTWgH1DaECKVa9NhdGph4LYXYBaX0,32337
42
+ rbrowser_cli/frontend/assets/fonts/opensans/OpenSans-Regular.ttf,sha256=ZTBIAnfaYu_eBH6ybnin5TLRz67skWA-aNY4drlmnw0,130832
43
+ rbrowser_cli/frontend/assets/fonts/opensans/font.png,sha256=0R5MMt5BXtEaEVmwz_CvDFr-8FRxwVaS3MXNdvmw4Bk,232432
44
+ rbrowser_cli/frontend/assets/g3d/genome.g3d,sha256=Zp17MaFjJtOTcPSdGPDzBGDw86qBCTgV0z8arFI8WCI,20159535
45
+ rbrowser_cli/frontend/assets/icon/settings.svg,sha256=j04um_twsh6yS19drZLdPh_1UtzR6A9Xb33s9BhVjPE,1462
46
+ rbrowser_cli/frontend/assets/textures/arrow_down.png,sha256=lqO0fMcMUgAjmxezt2GeD4EgHp3rj6auzI6PmsUds4I,21859
47
+ rbrowser_cli/frontend/assets/textures/arrow_up.png,sha256=V0h5mLz5CCk6vlnnICihLsAk_biSeDjLFY_tH7Jv0OE,21839
48
+ rbrowser_cli/frontend/assets/textures/ball_gray.png,sha256=_6ax1dwnbn_o8nJ0hWPo_nSgc_4k8ASrMUGi_zsugGg,2696
49
+ rbrowser_cli/frontend/assets/textures/ball_gray3.png,sha256=ulC1gz8JdkmBGMxnn719O4JG-zi0C-sZz0hgR3N5A6c,2715
50
+ rbrowser_cli/frontend/assets/textures/ball_gray_10x10.png,sha256=PUE9YuLvGIfcsv9LENHuOzarDbnSk8KVkk0y5qgnPUM,310
51
+ rbrowser_cli/frontend/assets/textures/ball_gray_5x5.png,sha256=A-W2Z-Ng55Eb63NKy-yaZJs0CpjeMH_B8zNXo3yJpMQ,2586
52
+ rbrowser_cli/frontend/assets/textures/ball_white_100.png,sha256=ei3U0ARayBelRbyNiM2nzVdIfIa2vS5_boEd9A-cOqw,5434
53
+ rbrowser_cli/frontend/assets/textures/ball_white_20.png,sha256=FRVWktUYg55UyBGV1jeh0GnMr5o-6kW7141ml6oOGKs,813
54
+ rbrowser_cli/frontend/assets/textures/ball_white_40.png,sha256=x1E3cgMpNInO7xLWYhVoBRhsUX8u4iOyV8JWMNrlX4c,2076
55
+ rbrowser_cli/frontend/assets/textures/base_A.png,sha256=tbtT2-7t5FQPsGUIhPk4HHWLwv2Lx7c7oXE7ztb6o2g,7346
56
+ rbrowser_cli/frontend/assets/textures/base_C.png,sha256=cHuHgU6Q2smvnIUvdF5u_Yy2VHowaDH0YjkqcgqgHfs,8569
57
+ rbrowser_cli/frontend/assets/textures/base_G.png,sha256=wXyLwdyQjNyk_b2ey06UGCpvoB069W24JJbG4i-ibJ0,8126
58
+ rbrowser_cli/frontend/assets/textures/base_T.png,sha256=HO3uS4tdgbxyEDET35LrMe2G0pM28D57Y2EW9BV6zjc,3325
59
+ rbrowser_cli/frontend/assets/textures/base_U.png,sha256=ROuudXbP-RhWCJDbFewS5_kNGJVGGsUeeNWWh-phWIk,5728
60
+ rbrowser_cli/frontend/assets/textures/circle_100.png,sha256=42AePsds1qmDBZ9jkTXmoopltMFaU04KKEz0WriSsXY,8522
61
+ rbrowser_cli/frontend/assets/textures/circle_black_100.png,sha256=brUhIvjISB08uQEULM8fYrlFePk6Xy5wb-W50o_5p1U,8083
62
+ rbrowser_cli/frontend/assets/textures/circle_red.png,sha256=Vu5IGGjO94gc2GCs2JXlIwRew0dTDSXNE-JMW3oAibs,10009
63
+ rbrowser_cli/frontend/assets/textures/circle_white_100.png,sha256=LvV42J7umsisYRFEPwAXGf_ccvLszdk56AspZ6YI3aA,7886
64
+ rbrowser_cli/frontend/assets/textures/diamond copy.png,sha256=6BFrb45G3bwldo1t7iDARyQg_1fs0969tztnd6yKhNg,371
65
+ rbrowser_cli/frontend/assets/textures/diamond.png,sha256=sfQjuOF-KJlWwsMxQlTnQXXY1oB7rUx5UOtjJ8lC1Ww,44768
66
+ rbrowser_cli/frontend/assets/textures/diamond2.png,sha256=w65fDZ_X7Bzs92LH5jjWL7FfRhiq1R-Y8QXLpenXhHc,314
67
+ rbrowser_cli/frontend/assets/textures/drop.png,sha256=N3H5BGS4DfXWVs_630mVPW7boZhjzWTW_iEq8x8HJ6I,483
68
+ rbrowser_cli/frontend/assets/textures/drop_line.png,sha256=CV5FEO2szj7n1IxzSbwRjy5x49qmhWr9Gg4Xkqsd8zU,510
69
+ rbrowser_cli/frontend/assets/textures/ele_gray.png,sha256=eMpEUXYczH95CXOV10hPk_lHtDkpgxSinf9lbEe6Fv8,2375
70
+ rbrowser_cli/frontend/assets/textures/ele_grays.png,sha256=MCg-ztE1oVPn_-o7vrCOvKo75jBjO2FgNg4PfIR-pBM,136
71
+ rbrowser_cli/frontend/assets/textures/ele_green.png,sha256=LXDhhgCBONRCU1tyZ9X0-O5LuV8uHlFtDdHyrhRGbMY,2392
72
+ rbrowser_cli/frontend/assets/textures/ele_ocean.png,sha256=fbjQhbSmYwwqcmKKuzkS53154Q1BSccZy4LvLaXpWZ4,2392
73
+ rbrowser_cli/frontend/assets/textures/ele_red.png,sha256=FZCWx98YMEN_T4RrtgjN2cZcKAdH76e2Uue6OhWhcIM,2387
74
+ rbrowser_cli/frontend/assets/textures/ele_sky.png,sha256=iAywvvBccAgdPNdDkn85UCXUvTFpcPrHeney21n6cqM,2389
75
+ rbrowser_cli/frontend/assets/textures/ele_soft_gray.png,sha256=nRpSPSTRbjcDN26QnTuxgkpOWSKPHM0asw9WGQzpvfs,2382
76
+ rbrowser_cli/frontend/assets/textures/ele_yellow.png,sha256=SY14gFNGw9MrcFloYqcDpz7Cg3TNa6BBCWQRUgebubg,2384
77
+ rbrowser_cli/frontend/assets/textures/texture.psd,sha256=3KwOi0MVmDvdaNBb9BEhP8JgzK4TSgZr6X_S5oHtsK8,263626
78
+ rbrowser_cli/frontend/assets/textures/texture_ATCG.psd,sha256=P-Gwlbzx5zCNrmBkU1TznBxuvwbTbYaBqeK_6nyGGUY,213792
79
+ rbrowser_cli/frontend/assets/textures/texture_circle_org.png,sha256=Oti8CBN6ljWzvclDWg7LVfN-dIRH13M3iFE5Co6ZYbA,1810
80
+ rbrowser_cli/frontend/assets/textures/texture_diamond.psd,sha256=rDXCw_HyaI_VBtw6sP1puj_zJhdKsoIweFZlC_dY2CA,198910
81
+ rbrowser_cli/frontend/assets/textures/texture_grey_border_main.png,sha256=8S2BJW5KuLvFnyZCKt6bqiGXRZZWhJKCos7reDcsc8c,197
82
+ rbrowser_cli/frontend/assets/textures/texture_grey_main.png,sha256=iWFA6H4kByM1j1oURKn9DkSsMv0kXs5rXz0EfTqJ3ZE,76028
83
+ rbrowser_cli/frontend/assets/textures/texture_grey_main.psd,sha256=mmASZen6wDAxAy0xBHKPmgtJ_EMlIGXpaj3SXHXiVJc,82382
84
+ rbrowser_cli/frontend/assets/textures/triangle.png,sha256=F8LqHivl9wY64ulzcQmLEb5sZ2zNylfVIJpFJ6M82FE,407
85
+ rbrowser_cli/frontend/static/css/index.ArNRqnY1.css,sha256=w5eZSq6ZyZsoCNTaKWo7FS4f2vymiqIVLm26SPm3GlQ,112455
86
+ rbrowser_cli/frontend/static/css/index.CroWzXsC.css,sha256=bk3AFBvJVLaohP472ymGizyaQ_o527ch2GVY7n8d5y4,5460
87
+ rbrowser_cli/frontend/static/css/index.DPMyIVYU.css,sha256=3yLV0nT9W5t57jLDy2kNcGc9vXiIkKUgotbW6NM1GlQ,11669
88
+ rbrowser_cli/frontend/static/js/AppstoreAddOutlined.D5ilOMxt.chunk.js,sha256=jIGy3QVU2k-3c7QCgAf60Gd-47rNl5zDktQQtyAVo8k,27363
89
+ rbrowser_cli/frontend/static/js/CheckCircleRounded.DVZy-MCf.chunk.js,sha256=GQTJSCoJCZAe6Q-XxDij5Z8nQxuFaW0aCIC0kABQcKI,518
90
+ rbrowser_cli/frontend/static/js/ClearAllRounded.CUJRdVDQ.chunk.js,sha256=JPiwFw-2cCz9DtzIcf_GWu9PKxeYTQhGElNHew6xMJs,1015
91
+ rbrowser_cli/frontend/static/js/ExpandMore.C46BDO5j.chunk.js,sha256=sCJhi7iUSmi4hMU5Xh8JFYW6C9p0rq1F_aZvWo98CPk,322
92
+ rbrowser_cli/frontend/static/js/Refresh.C83YUbTk.chunk.js,sha256=fXyIKZW2IW4MNAgq0FEot5WPcEYmdaVWG80WXp_FXls,1079
93
+ rbrowser_cli/frontend/static/js/d3-vendor.D2vplkPo.chunk.js,sha256=ZXgyPIn13wNEwQvik4MZ1GZJ_gfCNk7IpOKjTilIMTA,71537
94
+ rbrowser_cli/frontend/static/js/datahub-data.BkMvslYe.chunk.js,sha256=VotTJPzcPzr_Uqyt2ml_241zyXgK8A_Qje6e3leiVYc,6495833
95
+ rbrowser_cli/frontend/static/js/index.B36BqAW0.chunk.js,sha256=Tl48boFv8niBA-YpXANmpkhpz79Iov0FIXvypuzJVgY,176
96
+ rbrowser_cli/frontend/static/js/index.B79vQDf2.chunk.js,sha256=TTpAsaVHEPtN5Kx6GyhdlTdtKwwx2FXD3EW2sB7WMMM,180
97
+ rbrowser_cli/frontend/static/js/index.D1QXMsT8.chunk.js,sha256=CJ31PkwVtebZKp98hu0ZOvcf_UUH44QNlVIsnx__dH0,18373
98
+ rbrowser_cli/frontend/static/js/index.DICxSQgm.chunk.js,sha256=PCINMimMQDYF8VZXpGr4-xvQkPL9kJa0kLUWwEsqU-0,19624
99
+ rbrowser_cli/frontend/static/js/index.DezPsQiY.chunk.js,sha256=h56O5_ZImi0RtlqOkwrmFPm65oLVfrmvz6Zls-UCELg,175
100
+ rbrowser_cli/frontend/static/js/index.DhVVPnZF.chunk.js,sha256=bROX10jslvgRLP0LrQnOqee_5E6KIvpDuhrsQ1X6blw,2711
101
+ rbrowser_cli/frontend/static/js/index.DpkFDdug.js,sha256=rN5kxxn66E3uqUIkQSfK1rWUoa_brv2sG91ZyeFGEzo,5414995
102
+ rbrowser_cli/frontend/static/js/index.JBr0C4Rc.chunk.js,sha256=M9VmxmyAkt2AoUCBLoKa2yjopkRPhSPGsJ5sktJZi5c,32889
103
+ rbrowser_cli/frontend/static/js/index.Lr6WmsZR.chunk.js,sha256=J08UvX0VNeB2Bfr3TZcArHpp1A5WwOysUFMQExRUZow,1125121
104
+ rbrowser_cli/frontend/static/js/index.Pv0g6RaM.chunk.js,sha256=VgMcGilSeh5zgLKzjnhxTcI5vIrHSScICQphKxQvYaU,20868
105
+ rbrowser_cli/frontend/static/js/index.WaMjEOTD.chunk.js,sha256=Y0OGdmChLqFp7pLX5Ne_a6x2Suoec7xHeWYyQN5_5nE,443226
106
+ rbrowser_cli/frontend/static/js/index.oG4Fdp8e.chunk.js,sha256=h5P76xwif2TLlEf08DcXoYBwStRwYtPOBZ5Qdhn2Ywk,173
107
+ rbrowser_cli/frontend/static/js/index.pFX21XGS.chunk.js,sha256=iJrFmGPUz1Ozbke_XmKbijeZar5JMiWvFI4wFrUik1s,362
108
+ rbrowser_cli/frontend/static/js/index.qnCfw2-y.chunk.js,sha256=TEyU4WT2m2W3bfAM7A6nw38hfgyvhki36mpPFi-3yOE,177
109
+ rbrowser_cli/frontend/static/js/mui-vendor.C2wT3-V2.chunk.js,sha256=xsADdOggWNyd80qGqqOxXrVOrkWlKnqoXANbPWqD4OA,538970
110
+ rbrowser_cli/frontend/static/js/pixi-vendor.DwNHHdM-.chunk.js,sha256=LrwCZ80dbg6w2J02B9DKgvMRg0kUP9cxWQUmFa17tO4,545356
111
+ rbrowser_cli/frontend/static/js/react-vendor.C018e_IG.chunk.js,sha256=zGww_42Hb3I8XbrnscR5deoSBq_uCVYrCB0RJDsvWnM,332907
112
+ rbrowser_cli/frontend/static/js/redux-vendor.BYT4ly2K.chunk.js,sha256=P1qsAkmzmQm8fYyTtks68O7pBxYBPLxVMyNCe3ywXlg,55608
113
+ rbrowser_cli/frontend/static/media/logo.BdaLZdU8.png,sha256=uXQVPYoVnmR1Va8zIaWR7lYCZAxtgI-aHLcPYW-l9i4,27833
114
+ rbrowser-0.1.6.dist-info/METADATA,sha256=3wJo4u7xYyZbogM-Lq9G8s_Hm2B1CyxjKHQLqoYU7q0,3979
115
+ rbrowser-0.1.6.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
116
+ rbrowser-0.1.6.dist-info/entry_points.txt,sha256=e_DDMn8YRILhEpxUlFOs5Isx92vXkqrTvGyhoQblKLg,51
117
+ rbrowser-0.1.6.dist-info/top_level.txt,sha256=2DRyc1CVp4w33iomZHKDf9BaEpnbduZxeW1sqNtyQaQ,13
118
+ rbrowser-0.1.6.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ rbrowser = rbrowser_cli.cli:main
@@ -0,0 +1 @@
1
+ rbrowser_cli
@@ -0,0 +1,3 @@
1
+ """RBrowser CLI — launch RBrowser with a local or remote directory."""
2
+
3
+ __version__ = "0.1.0"
rbrowser_cli/cli.py ADDED
@@ -0,0 +1,143 @@
1
+ """Click CLI entry-point for ``rbrowser``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import socket
6
+ import sys
7
+ from pathlib import Path
8
+ from urllib.parse import quote, urlencode
9
+
10
+ import click
11
+ from werkzeug.serving import make_server
12
+
13
+ from .output import is_remote_session, print_banner
14
+ from .path_parser import parse_path
15
+
16
+
17
+ FRONTEND_FALLBACK = "https://rbrowser.org"
18
+ _BUNDLED_FRONTEND_DIR = Path(__file__).parent / "frontend"
19
+
20
+
21
+ def _has_bundled_frontend() -> bool:
22
+ return (_BUNDLED_FRONTEND_DIR / "index.html").is_file()
23
+
24
+
25
+ def _pick_port(preferred: int) -> int:
26
+ """Return an available port. If ``preferred`` is 0, OS picks one."""
27
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
28
+ try:
29
+ s.bind(("0.0.0.0", preferred))
30
+ except OSError as e:
31
+ raise click.ClickException(f"Port {preferred} is not available: {e}") from e
32
+ return s.getsockname()[1]
33
+
34
+
35
+ def _detect_host_for_url(is_remote_cli: bool) -> str:
36
+ """Pick the host the user's browser should connect to.
37
+
38
+ - When the CLI runs locally, ``localhost`` is the safest default.
39
+ - When the CLI runs on a remote SSH server, fall back to the externally
40
+ visible hostname / first non-loopback IPv4 so the user's local browser
41
+ can reach it (or, if SSH port-forwarding is set up, ``localhost``).
42
+ """
43
+ if not is_remote_cli:
44
+ return "localhost"
45
+ try:
46
+ host = socket.gethostname()
47
+ ip = socket.gethostbyname(host)
48
+ if ip and not ip.startswith("127."):
49
+ return host
50
+ except OSError:
51
+ pass
52
+ return "localhost"
53
+
54
+
55
+ @click.group()
56
+ @click.version_option()
57
+ def cli() -> None:
58
+ """RBrowser CLI."""
59
+
60
+
61
+ @cli.command("open")
62
+ @click.argument("path")
63
+ @click.option("--port", "-p", type=int, default=0, show_default=False,
64
+ help="Port to bind (default: random free port).")
65
+ @click.option("--frontend", default=None,
66
+ help=("RBrowser frontend. Default: bundled (if installed), else "
67
+ f"{FRONTEND_FALLBACK}. Pass an http(s):// URL to override."))
68
+ @click.option("--host", default="0.0.0.0", show_default=True,
69
+ help="Bind address for the file server.")
70
+ def open_cmd(path: str, port: int, frontend: str | None, host: str) -> None:
71
+ """Start the file server for PATH and open RBrowser.
72
+
73
+ PATH may be a local directory or ``user@host:/remote/path``.
74
+ """
75
+ parsed = parse_path(path)
76
+
77
+ # Decide frontend mode: bundled (served from this same server) vs external URL.
78
+ use_bundled = False
79
+ if frontend is None:
80
+ if _has_bundled_frontend():
81
+ use_bundled = True
82
+ else:
83
+ frontend = FRONTEND_FALLBACK
84
+ elif frontend.lower() in ("bundled", "local"):
85
+ if not _has_bundled_frontend():
86
+ raise click.ClickException(
87
+ "Bundled frontend not found. Reinstall rbrowser-cli or pass --frontend URL."
88
+ )
89
+ use_bundled = True
90
+
91
+ static_dir = str(_BUNDLED_FRONTEND_DIR) if use_bundled else None
92
+
93
+ if parsed.is_remote:
94
+ from .server_ssh import create_app
95
+ app = create_app(parsed.ssh_target, parsed.path, static_dir=static_dir)
96
+ else:
97
+ from .server_local import create_app
98
+ app = create_app(parsed.path, static_dir=static_dir)
99
+
100
+ bound_port = _pick_port(port) if port else _pick_port(0)
101
+ remote_session = is_remote_session()
102
+ url_host = _detect_host_for_url(remote_session)
103
+
104
+ server_url = f"http://{url_host}:{bound_port}"
105
+ if use_bundled:
106
+ # Bundled frontend: served from the same origin → only need ?root=.
107
+ # The frontend infers fileServerUrl from window.location.
108
+ qs = urlencode({"root": parsed.display()}, quote_via=quote)
109
+ frontend_url = f"{server_url}/#/main?{qs}"
110
+ else:
111
+ # External UI: must include fileServerUrl (different origin).
112
+ qs = urlencode({
113
+ "fileServerUrl": server_url,
114
+ "root": parsed.display(),
115
+ }, quote_via=quote)
116
+ frontend_url = f"{frontend.rstrip('/')}/#/main?{qs}"
117
+
118
+ print_banner(
119
+ server_url=server_url,
120
+ frontend_url=frontend_url,
121
+ root_display=parsed.display(),
122
+ is_remote=remote_session,
123
+ bundled=use_bundled,
124
+ )
125
+
126
+ server = make_server(host, bound_port, app, threaded=True)
127
+ try:
128
+ server.serve_forever()
129
+ except KeyboardInterrupt:
130
+ click.echo("\nShutting down…")
131
+ server.shutdown()
132
+
133
+
134
+ def main() -> None:
135
+ try:
136
+ cli()
137
+ except click.ClickException as e:
138
+ e.show()
139
+ sys.exit(e.exit_code)
140
+
141
+
142
+ if __name__ == "__main__":
143
+ main()