Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clear the downloading history when test/ directory is empty #766

Merged
merged 2 commits into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ If you cannot install online-judge-tools even following the instructions, please
### Other questions

- I usually make one directory per one contest (or, site). Can I keep using this style?
- Yes, you can use the `--directory` (`-d`) option. However, we don't recommend this style, because you should make additional test cases by yourself and run stress tests to maximize your rating.
- Yes, you can use the `--directory` (`-d`) option or `$ rm -rf test/`. However, we don't recommend this style, because you should make additional test cases by yourself and run stress tests to maximize your rating.
- Can I download all sample cases of all problems at once?
- No, but you can use `oj-prepare` command in [kmyk/online-judge-template-generator](https://github.com/kmyk/online-judge-template-generator).
- Can I automatically compile my source code before testing?
Expand Down
16 changes: 13 additions & 3 deletions onlinejudge_command/download_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,27 @@ class DownloadHistory(object):
def __init__(self, path: pathlib.Path = utils.user_cache_dir / 'download-history.jsonl'):
self.path = path

def add(self, problem: Problem, directory: pathlib.Path = pathlib.Path.cwd()) -> None:
def add(self, problem: Problem, *, directory: pathlib.Path) -> None:
log.status('append the downloading history: %s', self.path)
self.path.parent.mkdir(parents=True, exist_ok=True)
with open(str(self.path), 'a') as fh:
fh.write(json.dumps({
'timestamp': int(time.time()), # this should not be int, but Python's strptime is too weak and datetime.fromisoformat is from 3.7
'directory': str(directory),
'url': problem.get_url(),
}) + '\n')
log.status('append history to: %s', self.path)
self._flush()

def remove(self, *, directory: pathlib.Path) -> None:
if not self.path.exists():
return
log.status('clear the downloading history for this directory: %s', self.path)
with open(str(self.path)) as fh:
history_lines = fh.readlines()
with open(str(self.path), 'w') as fh:
pred = lambda line: pathlib.Path(json.loads(line)['directory']) != directory
fh.write(''.join(filter(pred, history_lines)))

def _flush(self) -> None:
# halve the size if it is more than 1MiB
if self.path.stat().st_size >= 1024 * 1024:
Expand All @@ -34,7 +44,7 @@ def _flush(self) -> None:
fh.write(''.join(history_lines[:-len(history_lines) // 2]))
log.status('halve history at: %s', self.path)

def get(self, directory: pathlib.Path = pathlib.Path.cwd()) -> List[str]:
def get(self, *, directory: pathlib.Path) -> List[str]:
if not self.path.exists():
return []

Expand Down
7 changes: 5 additions & 2 deletions onlinejudge_command/subcommand/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,13 @@ def download(args: 'argparse.Namespace') -> None:
if not samples:
raise SampleParseError("Sample not found")

# append the history for submit command
# append the history for submit subcommand
if not args.dry_run and is_default_format:
history = onlinejudge_command.download_history.DownloadHistory()
history.add(problem)
if not list(args.directory.glob('*')):
# reset the history to help users who use only one directory for many problems
history.remove(directory=pathlib.Path.cwd())
history.add(problem, directory=pathlib.Path.cwd())

# prepare files to write
def iterate_files_to_write(sample: TestCase, *, i: int) -> Iterator[Tuple[str, pathlib.Path, bytes]]:
Expand Down
2 changes: 1 addition & 1 deletion onlinejudge_command/subcommand/submit.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def submit(args: 'argparse.Namespace') -> None:
# guess url
history = onlinejudge_command.download_history.DownloadHistory()
if args.file.parent.resolve() == pathlib.Path.cwd():
guessed_urls = history.get()
guessed_urls = history.get(directory=pathlib.Path.cwd())
else:
log.warning('cannot guess URL since the given file is not in the current directory')
guessed_urls = []
Expand Down
19 changes: 18 additions & 1 deletion tests/command_submit.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import shutil
import time
import unittest

Expand All @@ -15,7 +16,7 @@

class SubmitArgumentsTest(unittest.TestCase):
@unittest.skipIf(not tests.utils.is_logged_in(AtCoderService()), 'login is required')
def test_call_submit_atcoder_practice_2_with_history(self):
def test_call_submit_atcoder_practice_2_with_history_simple(self):

url = 'https://atcoder.jp/contests/practice/tasks/practice_2'
files = [
Expand All @@ -28,6 +29,22 @@ def test_call_submit_atcoder_practice_2_with_history(self):
tests.utils.run(['dl', url], check=False)
tests.utils.run(['s', '-y', '--no-open', url, 'a.cpp'], check=True)

@unittest.skipIf(not tests.utils.is_logged_in(AtCoderService()), 'login is required')
def test_call_submit_atcoder_practice_2_with_history_remove(self):

url = 'https://atcoder.jp/contests/practice/tasks/practice_2'
files = [
{
'path': 'a.cpp',
'data': 'compile error'
},
]
with tests.utils.sandbox(files):
tests.utils.run(['dl', 'https://atcoder.jp/contests/abc099/tasks/abc099_a'], check=True)
shutil.rmtree('test/')
tests.utils.run(['dl', url], check=False)
tests.utils.run(['s', '-y', '--no-open', url, 'a.cpp'], check=True)

@unittest.skipIf(os.name == 'nt', "shell script doesn't work on Windows")
@unittest.skipIf(not tests.utils.is_logged_in(AtCoderService()), 'login is required')
def test_call_submit_atcoder_practice_1_with_open(self):
Expand Down