rbx.cp 0.5.63__py3-none-any.whl → 0.5.64__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.
- rbx/box/contest/build_contest_statements.py +2 -1
- rbx/box/formatting.py +25 -0
- rbx/box/packaging/boca/upload.py +18 -0
- rbx/box/packaging/main.py +4 -3
- rbx/box/setter_config.py +4 -0
- rbx/box/solutions.py +10 -10
- rbx/box/statements/build_statements.py +2 -1
- {rbx_cp-0.5.63.dist-info → rbx_cp-0.5.64.dist-info}/METADATA +1 -1
- {rbx_cp-0.5.63.dist-info → rbx_cp-0.5.64.dist-info}/RECORD +12 -12
- {rbx_cp-0.5.63.dist-info → rbx_cp-0.5.64.dist-info}/LICENSE +0 -0
- {rbx_cp-0.5.63.dist-info → rbx_cp-0.5.64.dist-info}/WHEEL +0 -0
- {rbx_cp-0.5.63.dist-info → rbx_cp-0.5.64.dist-info}/entry_points.txt +0 -0
@@ -10,6 +10,7 @@ from rbx import console, testing_utils
|
|
10
10
|
from rbx.box import cd, package
|
11
11
|
from rbx.box.contest.contest_package import get_problems
|
12
12
|
from rbx.box.contest.schema import Contest, ContestProblem, ContestStatement
|
13
|
+
from rbx.box.formatting import href
|
13
14
|
from rbx.box.schema import Package, Testcase
|
14
15
|
from rbx.box.statements import build_statements
|
15
16
|
from rbx.box.statements.build_statements import (
|
@@ -344,6 +345,6 @@ def build_statement(
|
|
344
345
|
console.console.print(
|
345
346
|
f'Statement built successfully for language '
|
346
347
|
f'[item]{statement.language}[/item] at '
|
347
|
-
f'
|
348
|
+
f'{href(statement_path)}'
|
348
349
|
)
|
349
350
|
return statement_path
|
rbx/box/formatting.py
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
import os
|
2
|
+
import pathlib
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
from rbx.box import setter_config
|
6
|
+
|
7
|
+
|
8
|
+
def href(url: os.PathLike[str], text: Optional[str] = None, style: str = 'item') -> str:
|
9
|
+
custom_text = False
|
10
|
+
if text is None:
|
11
|
+
text = str(url)
|
12
|
+
else:
|
13
|
+
custom_text = True
|
14
|
+
|
15
|
+
if not custom_text:
|
16
|
+
if not setter_config.get_setter_config().hyperlinks:
|
17
|
+
return f'[{style}]{text}[/{style}]'
|
18
|
+
if os.environ.get('TERM') in ['vscode']:
|
19
|
+
return f'[{style}]{text}[/{style}]'
|
20
|
+
|
21
|
+
if isinstance(url, pathlib.Path):
|
22
|
+
url = url.resolve()
|
23
|
+
return f'[{style}][link={url}]{text}[/link][/{style}]'
|
24
|
+
|
25
|
+
|
1
26
|
def get_formatted_memory(memory_in_bytes: int, mib_decimal_places: int = 0) -> str:
|
2
27
|
if memory_in_bytes < 1024 * 1024:
|
3
28
|
if memory_in_bytes < 1024:
|
rbx/box/packaging/boca/upload.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import datetime
|
2
|
+
import functools
|
2
3
|
import hashlib
|
3
4
|
import os
|
4
5
|
import pathlib
|
@@ -41,6 +42,8 @@ class BocaUploader:
|
|
41
42
|
self.username = _parse_env_var('BOCA_USERNAME', username)
|
42
43
|
self.password = _parse_env_var('BOCA_PASSWORD', password)
|
43
44
|
|
45
|
+
self.loggedIn = False
|
46
|
+
|
44
47
|
self.br = mechanize.Browser()
|
45
48
|
self.br.set_handle_robots(False)
|
46
49
|
self.br.addheaders = [ # type: ignore
|
@@ -140,6 +143,9 @@ class BocaUploader:
|
|
140
143
|
return self.log_response_alert(response, error_msg)
|
141
144
|
|
142
145
|
def login(self):
|
146
|
+
if self.loggedIn:
|
147
|
+
return
|
148
|
+
|
143
149
|
_, html = self.open(
|
144
150
|
f'{self.base_url}', error_msg='Error while opening BOCA login page'
|
145
151
|
)
|
@@ -157,6 +163,8 @@ class BocaUploader:
|
|
157
163
|
login_url = f'{self.base_url}?name={self.username}&password={pwd_hash}'
|
158
164
|
self.open(login_url, error_msg='Error while logging in to BOCA')
|
159
165
|
|
166
|
+
self.loggedIn = True
|
167
|
+
|
160
168
|
def upload(self, file: pathlib.Path) -> bool:
|
161
169
|
self.open(
|
162
170
|
f'{self.base_url}/admin/problem.php',
|
@@ -226,6 +234,7 @@ class BocaUploader:
|
|
226
234
|
console.console.print(
|
227
235
|
f'[warning]Potentially transient error while uploading problem to BOCA. Retrying ({tries}/{RETRIES})...[/warning]'
|
228
236
|
)
|
237
|
+
self.loggedIn = False
|
229
238
|
continue
|
230
239
|
|
231
240
|
ok = True
|
@@ -245,3 +254,12 @@ class BocaUploader:
|
|
245
254
|
'[warning]Check [item]https://www.php.net/manual/en/ini.core.php#ini.sect.file-uploads[/item] for more information.[/warning]'
|
246
255
|
)
|
247
256
|
raise typer.Exit(1)
|
257
|
+
|
258
|
+
|
259
|
+
@functools.lru_cache
|
260
|
+
def get_boca_uploader(
|
261
|
+
base_url: Optional[str] = None,
|
262
|
+
username: Optional[str] = None,
|
263
|
+
password: Optional[str] = None,
|
264
|
+
) -> BocaUploader:
|
265
|
+
return BocaUploader(base_url, username, password)
|
rbx/box/packaging/main.py
CHANGED
@@ -7,6 +7,7 @@ import typer
|
|
7
7
|
|
8
8
|
from rbx import annotations, console
|
9
9
|
from rbx.box import environment, header, package
|
10
|
+
from rbx.box.formatting import href
|
10
11
|
from rbx.box.naming import get_problem_name_with_contest_info
|
11
12
|
from rbx.box.package import get_build_path
|
12
13
|
from rbx.box.packaging.packager import BasePackager, BuiltStatement
|
@@ -62,7 +63,7 @@ async def run_packager(
|
|
62
63
|
console.console.print(
|
63
64
|
f'[success]Problem packaged for [item]{packager.name()}[/item]![/success]'
|
64
65
|
)
|
65
|
-
console.console.print(f'Package was saved at
|
66
|
+
console.console.print(f'Package was saved at {href(result_path)}')
|
66
67
|
return result_path
|
67
68
|
|
68
69
|
|
@@ -105,9 +106,9 @@ async def boca(
|
|
105
106
|
result_path = await run_packager(BocaPackager, verification=verification)
|
106
107
|
|
107
108
|
if upload:
|
108
|
-
from rbx.box.packaging.boca.upload import
|
109
|
+
from rbx.box.packaging.boca.upload import get_boca_uploader
|
109
110
|
|
110
|
-
uploader =
|
111
|
+
uploader = get_boca_uploader()
|
111
112
|
uploader.login_and_upload(result_path)
|
112
113
|
|
113
114
|
|
rbx/box/setter_config.py
CHANGED
@@ -71,6 +71,10 @@ class SetterConfig(BaseModel):
|
|
71
71
|
default={},
|
72
72
|
description='Substitutions to apply to commands before running them.',
|
73
73
|
)
|
74
|
+
hyperlinks: bool = Field(
|
75
|
+
default=True,
|
76
|
+
description='Whether to use hyperlinks in the terminal output.',
|
77
|
+
)
|
74
78
|
|
75
79
|
def substitute_command(self, command: str, sanitized: bool = False) -> str:
|
76
80
|
exe = shlex.split(command)[0]
|
rbx/box/solutions.py
CHANGED
@@ -26,7 +26,7 @@ from rbx.box.deferred import Deferred
|
|
26
26
|
from rbx.box.environment import (
|
27
27
|
VerificationLevel,
|
28
28
|
)
|
29
|
-
from rbx.box.formatting import get_formatted_memory, get_formatted_time
|
29
|
+
from rbx.box.formatting import get_formatted_memory, get_formatted_time, href
|
30
30
|
from rbx.box.generators import (
|
31
31
|
GenerationMetadata,
|
32
32
|
expand_generator_call,
|
@@ -166,7 +166,7 @@ def compile_solutions(
|
|
166
166
|
):
|
167
167
|
continue
|
168
168
|
if progress:
|
169
|
-
progress.update(f'Compiling solution
|
169
|
+
progress.update(f'Compiling solution {href(solution.path)}...')
|
170
170
|
try:
|
171
171
|
compiled_solutions[solution.path] = compile_item(
|
172
172
|
solution,
|
@@ -176,7 +176,7 @@ def compile_solutions(
|
|
176
176
|
)
|
177
177
|
except:
|
178
178
|
console.console.print(
|
179
|
-
f'[error]Failed compiling solution
|
179
|
+
f'[error]Failed compiling solution {href(solution.path)}.[/error]'
|
180
180
|
)
|
181
181
|
raise
|
182
182
|
|
@@ -204,7 +204,7 @@ def _run_solution(
|
|
204
204
|
|
205
205
|
if progress:
|
206
206
|
progress.update(
|
207
|
-
f'Running solution
|
207
|
+
f'Running solution {href(solution.path)} on test [item]{group.name}[/item] / [item]{i}[/item]...'
|
208
208
|
)
|
209
209
|
|
210
210
|
async def run_fn(i=i, testcase=testcase, output_path=output_path):
|
@@ -1026,8 +1026,8 @@ def _print_solution_header(
|
|
1026
1026
|
solution: SolutionSkeleton,
|
1027
1027
|
console: rich.console.Console,
|
1028
1028
|
):
|
1029
|
-
console.print(f'
|
1030
|
-
console.print(f'({solution.runs_dir})')
|
1029
|
+
console.print(f'{href(solution.path)}', end=' ')
|
1030
|
+
console.print(f'({href(solution.runs_dir, style="info")})')
|
1031
1031
|
|
1032
1032
|
|
1033
1033
|
@dataclasses.dataclass
|
@@ -1052,14 +1052,14 @@ class TimingSummary:
|
|
1052
1052
|
def print(self, console: rich.console.Console, tl: Optional[int] = None):
|
1053
1053
|
if self.slowest_good is not None:
|
1054
1054
|
console.print(
|
1055
|
-
f'Slowest [success]OK[/success] solution: {self.slowest_good.time} ms,
|
1055
|
+
f'Slowest [success]OK[/success] solution: {self.slowest_good.time} ms, {href(self.slowest_good.solution.path)}'
|
1056
1056
|
)
|
1057
1057
|
if self.fastest_slow is not None:
|
1058
1058
|
fastest_slow = self.fastest_slow.time
|
1059
1059
|
if tl is not None and self.fastest_slow.time > tl:
|
1060
1060
|
fastest_slow = f'>{tl}'
|
1061
1061
|
console.print(
|
1062
|
-
f'Fastest [error]slow[/error] solution: {fastest_slow} ms,
|
1062
|
+
f'Fastest [error]slow[/error] solution: {fastest_slow} ms, {href(self.fastest_slow.solution.path)}'
|
1063
1063
|
)
|
1064
1064
|
|
1065
1065
|
|
@@ -1184,7 +1184,7 @@ async def _render_detailed_group_table(
|
|
1184
1184
|
) -> rich.table.Table:
|
1185
1185
|
table = rich.table.Table()
|
1186
1186
|
for solution in skeleton.solutions:
|
1187
|
-
table.add_column(f'
|
1187
|
+
table.add_column(f'{href(solution.path)}', justify='full')
|
1188
1188
|
|
1189
1189
|
padded_rows = []
|
1190
1190
|
|
@@ -1424,7 +1424,7 @@ async def estimate_time_limit(
|
|
1424
1424
|
|
1425
1425
|
if not timings:
|
1426
1426
|
console.print(
|
1427
|
-
f'[warning]No timings for solution
|
1427
|
+
f'[warning]No timings for solution {href(solution.path)}.[/warning]'
|
1428
1428
|
)
|
1429
1429
|
continue
|
1430
1430
|
|
@@ -8,6 +8,7 @@ import typer
|
|
8
8
|
|
9
9
|
from rbx import annotations, console
|
10
10
|
from rbx.box import environment, naming, package
|
11
|
+
from rbx.box.formatting import href
|
11
12
|
from rbx.box.schema import Package
|
12
13
|
from rbx.box.statements.builders import (
|
13
14
|
BUILDER_LIST,
|
@@ -302,7 +303,7 @@ def build_statement(
|
|
302
303
|
console.console.print(
|
303
304
|
f'Statement built successfully for language '
|
304
305
|
f'[item]{statement.language}[/item] at '
|
305
|
-
f'
|
306
|
+
f'{href(statement_path)}'
|
306
307
|
)
|
307
308
|
return statement_path
|
308
309
|
|
@@ -10,7 +10,7 @@ rbx/box/code.py,sha256=2oC1JbZiwfeg53ZICPig-KJYchqFRIZz-inlM-cLc7Q,19911
|
|
10
10
|
rbx/box/compile.py,sha256=OJLthDQ921w9vyoE6Gk1Df54i5RwtRJ2YG-8XEfefcs,2489
|
11
11
|
rbx/box/conftest.py,sha256=sEmciXSeDC-wmrZ1JSxbsUenKNP_VWW32mrCun2pY3I,1070
|
12
12
|
rbx/box/contest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
-
rbx/box/contest/build_contest_statements.py,sha256=
|
13
|
+
rbx/box/contest/build_contest_statements.py,sha256=DtbzLShc8zzbjE-1sBFtPY3JGhSwm48q6eSOPYWSVxQ,11399
|
14
14
|
rbx/box/contest/contest_package.py,sha256=OaUbpBtkhkgOPzJ1ccI_Vq4FMSaJvZm3gMOKfVY8oy4,3032
|
15
15
|
rbx/box/contest/contest_utils.py,sha256=TDE7I6YQJlu4dQd68wzOp019bNgqiT0RlM-LMQMjL9w,301
|
16
16
|
rbx/box/contest/main.py,sha256=u76kAQSVWEuyGLqVgyjXwYxJwHXAeEHMwbM7MfenKvE,7574
|
@@ -22,7 +22,7 @@ rbx/box/download.py,sha256=DxAiAk4lDYWEz1C9UTvZzHTq6hgm4fxGezApm2IkCTM,2601
|
|
22
22
|
rbx/box/dump_schemas.py,sha256=3j5t47_vJmXj0BCczxDX6ByOcsfolGEDNCBXlPpk86w,593
|
23
23
|
rbx/box/environment.py,sha256=Kp69MekUwwoVpupnafUcN5KAbP-ZTCwe0OQXt1h0FN8,11859
|
24
24
|
rbx/box/extensions.py,sha256=Von8kIeXvNFTkGlMRMTvL2HIHPwlkuiMswr-ydbGV1w,519
|
25
|
-
rbx/box/formatting.py,sha256=
|
25
|
+
rbx/box/formatting.py,sha256=csscjgWrTa6zjs2ueVCFRzA3WxdUFbzkzOxHWyQVerw,1049
|
26
26
|
rbx/box/generators.py,sha256=RE0-D91BB-3rNDQXvCFWzU9iMhKIc_ALp960oGfM-rY,13780
|
27
27
|
rbx/box/generators_test.py,sha256=J7aBfuJhU84MWDWzgReRoOuQw_hVa09B8gTKAvL2XVo,1987
|
28
28
|
rbx/box/git_utils.py,sha256=VlUgzuHOCnrjjiJQnDB32qDHbHw_zkwgA7wm4bloibc,750
|
@@ -34,9 +34,9 @@ rbx/box/naming.py,sha256=pOG37X_wQM9CCSYwJIUf-b-ZHEs_nchO7wQEdP_quJg,1367
|
|
34
34
|
rbx/box/package.py,sha256=pRsA5UsKNnD2uJcm8x01uQHUbCxoLbJvhoeqf3nyrew,14290
|
35
35
|
rbx/box/packaging/boca/extension.py,sha256=EQALNEOv4zVDXSKs_dk11n92y7cBZVn8TogIK683lE0,890
|
36
36
|
rbx/box/packaging/boca/packager.py,sha256=kiCcP9roRCiDU0Xr5PDKO83W1yN6cyg-EKMF9fxE0EY,11950
|
37
|
-
rbx/box/packaging/boca/upload.py,sha256=
|
37
|
+
rbx/box/packaging/boca/upload.py,sha256=y3DNMLNZyAwMdfBLUZRzxnr8cHwLegpH_NtgKW2Zwvw,9260
|
38
38
|
rbx/box/packaging/contest_main.py,sha256=UsRfIdNmOf0iLUbzgjxzyECfMuCQINstG1SCClGHaUQ,2808
|
39
|
-
rbx/box/packaging/main.py,sha256=
|
39
|
+
rbx/box/packaging/main.py,sha256=kLFcMz0xOTZgtJh6P0Rr-zfq0NCbvx7HiQQ_0YmsvGg,3826
|
40
40
|
rbx/box/packaging/moj/packager.py,sha256=FjghOe5CPlaF1GqK0NZgWVV_eYWpdTmz88bh04yeAyI,8708
|
41
41
|
rbx/box/packaging/packager.py,sha256=da2haC1L9cG30myneMrRIAdGubtid0Xmy38BHKPCZZ4,3633
|
42
42
|
rbx/box/packaging/polygon/packager.py,sha256=GfZ-Dc2TDKkb3QNnfOy8yxldho2L401Ao06oWg--Gcs,11714
|
@@ -51,12 +51,12 @@ rbx/box/presets/schema.py,sha256=mZmSPkQsw7eQM0lQN6er1MO_LiW1ObwwAZFDK0F5fxE,196
|
|
51
51
|
rbx/box/retries.py,sha256=cZcNYLVHFDbhbeqMzxITgo8SYY8qzyxm0tIYcmWl1Ek,4877
|
52
52
|
rbx/box/sanitizers/warning_stack.py,sha256=RI97_GJgdjTKIXY_r0EKp5h0qQQSDSdNDh5K7zINrqs,2861
|
53
53
|
rbx/box/schema.py,sha256=y736-wZdGw56T6eDC_m7NAm2XRUdauBXJRQkQO79fpc,16264
|
54
|
-
rbx/box/setter_config.py,sha256=
|
55
|
-
rbx/box/solutions.py,sha256=
|
54
|
+
rbx/box/setter_config.py,sha256=9iObg6BwxQhFAhIOk31Jc0BDDpRYVGf3SyLIOsWIltM,4393
|
55
|
+
rbx/box/solutions.py,sha256=pQG_4HVpFds6C0gcxmvKr557s7IhYmLoYB_s_1GgtAI,49049
|
56
56
|
rbx/box/solutions_test.py,sha256=PX1TQoRzNd9mi1SGsG7WFrpqFgNrNX5Kwt0mkwFdoOA,1749
|
57
57
|
rbx/box/state.py,sha256=MMf3DvfQji0jKEliCHct2Tpp_0epL1tvP8HbHNArQIc,166
|
58
58
|
rbx/box/statements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
|
-
rbx/box/statements/build_statements.py,sha256=
|
59
|
+
rbx/box/statements/build_statements.py,sha256=lu3mwm-ZID0N_t_6FIrCcMFjlqa5JR49PQ28dq2C3s8,12169
|
60
60
|
rbx/box/statements/builders.py,sha256=6lYV-cnC-NXMnJf1wasbq_AMbjdIuPpMirm7QsjZI6s,11825
|
61
61
|
rbx/box/statements/joiners.py,sha256=jItNXkAbTjFQpPMgfDMW86n3vMTbaE8sgo9I8Yf4Txg,2886
|
62
62
|
rbx/box/statements/latex.py,sha256=LkcHwXjMFxbw--Gj9T1VkFKQFsXhY9dN7xZHpZycNW8,1346
|
@@ -212,8 +212,8 @@ rbx/testcase.py,sha256=yKOq3CAJZ1YTmInvnoIs0u1iJnRj_X85XiWbLI-p9d8,1951
|
|
212
212
|
rbx/testcase_rendering.py,sha256=nfmv6dSEqd4aR3TsaODwkKGK6AXty_DDKtWf_ejiQpI,2084
|
213
213
|
rbx/testing_utils.py,sha256=x_PqD8Zd2PkN91NxVHUnSTs044-1WK5KKtttKQBXpFs,2083
|
214
214
|
rbx/utils.py,sha256=SfR844_i0ebRDMkmS_w1YdZiWPc6h2RGADygewlWRbA,4845
|
215
|
-
rbx_cp-0.5.
|
216
|
-
rbx_cp-0.5.
|
217
|
-
rbx_cp-0.5.
|
218
|
-
rbx_cp-0.5.
|
219
|
-
rbx_cp-0.5.
|
215
|
+
rbx_cp-0.5.64.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
216
|
+
rbx_cp-0.5.64.dist-info/METADATA,sha256=rBpsAACES-Q_TSMl1doYvu3m29ymEtfkYx62vfrI75E,3604
|
217
|
+
rbx_cp-0.5.64.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
218
|
+
rbx_cp-0.5.64.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
|
219
|
+
rbx_cp-0.5.64.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|