Skip to content

Commit

Permalink
Merge pull request #28 from online-judge-tools/fix/10
Browse files Browse the repository at this point in the history
Allow using relative paths for the argument of -t option of oj-template command
  • Loading branch information
kmyk authored Jun 19, 2020
2 parents fb01e2e + c584849 commit 572f2e9
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 46 deletions.
24 changes: 20 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ $ oj-prepare URL
- `main.cpp`: C++ 解法コード
- `main.py`: Python 解法コード
- `generate.py`: Python ランダムケース生成器
- `generate.cpp`: C++ ランダムケース生成器

(他にもいくつかありますが、それらは突然削除されることがあります。)

### Generating random cases

Expand Down Expand Up @@ -173,11 +175,25 @@ $ tree

## Settings

`oj-template` のためのテンプレートは `~/.config/online-judge-tools/template/` の下に `~/.config/online-judge-tools/template/customized.py` のように作って `oj-template -t customized.py https://...` のように指定する。
テンプレート記法は [Mako](https://www.makotemplates.org/) のものを使う。
[fastio.cpp](https://github.com/kmyk/online-judge-template-generator/blob/master/onlinejudge_template_resources/template/fastio.cpp) とか [customize_sample.cpp](https://github.com/kmyk/online-judge-template-generator/blob/master/onlinejudge_template_resources/template/customize_sample.cpp) とかを見てそれっぽく書けば動く。
### oj-template

`oj-prepare` の設定は `~/.config/online-judge-tools/prepare.config.toml` に次のように設定する。
`oj-template` のためのテンプレートは `-t` オプションによって指摘できます。
組み込みで用意されているテンプレートの一覧は [onlinejudge_template_resources/template/](https://github.com/online-judge-tools/template-generator/tree/master/onlinejudge_template_resources/template) で見られます。
たとえば [generate.cpp](https://github.com/online-judge-tools/template-generator/blob/master/onlinejudge_template_resources/template/generate.cpp) を利用したい場合は `oj-template -t generate.cpp https://...` としてください。

テンプレートを自分で作成することもできます。
テンプレート記法は [Mako](https://www.makotemplates.org/) のものを使います。
[fastio.cpp](https://github.com/kmyk/online-judge-template-generator/blob/master/onlinejudge_template_resources/template/fastio.cpp) とか [customize_sample.cpp](https://github.com/kmyk/online-judge-template-generator/blob/master/onlinejudge_template_resources/template/customize_sample.cpp) とかを見ていい感じに書いてください。
API ドキュメントは [onlinejudge_template.generator package](https://online-judge-template-generator.readthedocs.io/en/latest/onlinejudge_template.generator.html) にあります。

自分で書いたテンプレートを指定するときは、文字列中にパス区切り文字 `/` が含まれるようにしてパスを指定してください (シェルスクリプトでの実行ファイルの指定と同様です)。
たとえば `customized.py` というテンプレートを書いたときは、`oj-template -t ./customized.py https://...``oj-template -t /path/to/customized.py https://...` のように指定してください。
また、ディレクトリ `~/.config/online-judge-tools/template/` の下に `~/.config/online-judge-tools/template/customized.py` のようにファイルを配置しておくことで、`oj-template -t customized.py https://...` のように指定できるようにもなります。`~/.config/online-judge-tools/template/` を使えば組み込みのテンプレートを上書きすることができます。

### oj-prepare

`oj-prepare` の設定は `~/.config/online-judge-tools/prepare.config.toml` で行えます。
以下のように書いてください。

``` toml
contest_directory = "~/Desktop/{service_domain}/{contest_id}/{problem_id}"
Expand Down
16 changes: 8 additions & 8 deletions onlinejudge_prepare/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
from typing import *

import appdirs
import onlinejudge_template.analyzer.combined
import onlinejudge_template.generator
import onlinejudge_template.network
import onlinejudge_template.analyzer.combined as analyzer
import onlinejudge_template.generator._main as generator
import onlinejudge_template.network as network
import requests
import toml

Expand Down Expand Up @@ -89,19 +89,19 @@ def prepare_problem(problem: onlinejudge.type.Problem, *, contest: Optional[onli
dir.parent.mkdir(parents=True, exist_ok=True)
with chdir(dir):
url = problem.get_url()
html = onlinejudge_template.network.download_html(url, session=session)
sample_cases = onlinejudge_template.network.download_sample_cases(url, session=session)
html = network.download_html(url, session=session)
sample_cases = network.download_sample_cases(url, session=session)

# analyze
resources = onlinejudge_template.analyzer.combined.prepare_from_html(html, url=url, sample_cases=sample_cases)
analyzed = onlinejudge_template.analyzer.combined.run(resources)
resources = analyzer.prepare_from_html(html, url=url, sample_cases=sample_cases)
analyzed = analyzer.run(resources)

for dest_str, template in table.items():
dest = pathlib.Path(dest_str)

# generate
try:
code = onlinejudge_template.generator.run(analyzed, template_file=template)
code = generator.run(analyzed, template_file=template)
except NotImplementedError as e:
logger.error('generator failed: %s', e)
continue
Expand Down
26 changes: 0 additions & 26 deletions onlinejudge_template/generator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,26 +0,0 @@
import pathlib
from typing import *

import appdirs
import mako.lookup
import mako.template
import pkg_resources
from onlinejudge_template.types import *


def run(analyzed: AnalyzerResult, *, template_file: str) -> bytes:
data: Dict[str, Any] = {
'analyzed': analyzed,
'config': {},
}
directories = [
str(pathlib.Path(appdirs.user_config_dir('online-judge-tools')) / 'template'),
pkg_resources.resource_filename('onlinejudge_template_resources', 'template'),
]
lookup = mako.lookup.TemplateLookup(directories=directories, input_encoding="utf-8", output_encoding="utf-8")
path = pathlib.Path(template_file)
if path.is_absolute() and path.exists():
with open(path, "rb") as fh:
lookup.put_string(template_file, fh.read())
template = lookup.get_template(template_file)
return template.render(data=data)
31 changes: 31 additions & 0 deletions onlinejudge_template/generator/_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import pathlib
from typing import *

import appdirs
import mako.lookup
import mako.template
import pkg_resources
from onlinejudge_template.types import *


def run(analyzed: AnalyzerResult, *, template_file: str) -> bytes:
"""
:raises: mako.exceptions.MakoException
"""

data: Dict[str, Any] = {
'analyzed': analyzed,
'config': {},
}
directories = [
str(pathlib.Path(appdirs.user_config_dir('online-judge-tools')) / 'template'),
pkg_resources.resource_filename('onlinejudge_template_resources', 'template'),
]
lookup = mako.lookup.TemplateLookup(directories=directories, input_encoding="utf-8", output_encoding="utf-8")
path = pathlib.Path(template_file)
has_slash = path.name != template_file # If template_file has path separators or any other things characteristic to paths, we use it as a path. This is a similar behavior to searching commands in shell.
if has_slash and path.exists():
with open(path, "rb") as fh:
lookup.put_string(template_file, fh.read())
template = lookup.get_template(template_file)
return template.render(data=data)
16 changes: 8 additions & 8 deletions onlinejudge_template/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
from logging import DEBUG, INFO, basicConfig, getLogger
from typing import *

import onlinejudge_template.analyzer.combined
import onlinejudge_template.generator
import onlinejudge_template.network
import onlinejudge_template.analyzer.combined as analyzer
import onlinejudge_template.generator._main as generator
import onlinejudge_template.network as network

import onlinejudge.dispatch
import onlinejudge.utils
Expand Down Expand Up @@ -33,18 +33,18 @@ def main(args: Optional[List[str]] = None) -> None:
url = problem.get_url() # normalize url
logger.debug('url: %s', url)
with onlinejudge.utils.with_cookiejar(onlinejudge.utils.get_default_session(), path=parsed.cookie) as session:
html = onlinejudge_template.network.download_html(url, session=session)
sample_cases = onlinejudge_template.network.download_sample_cases(url, session=session)
html = network.download_html(url, session=session)
sample_cases = network.download_sample_cases(url, session=session)
logger.debug('sample cases: %s', sample_cases)

# analyze
resources = onlinejudge_template.analyzer.combined.prepare_from_html(html, url=url, sample_cases=sample_cases)
resources = analyzer.prepare_from_html(html, url=url, sample_cases=sample_cases)
logger.debug('analyzer resources: %s', resources._replace(html=b'...skipped...'))
analyzed = onlinejudge_template.analyzer.combined.run(resources)
analyzed = analyzer.run(resources)
logger.debug('analyzed result: %s', analyzed._replace(resources=analyzed.resources._replace(html=b'...skipped...')))

# generate
code = onlinejudge_template.generator.run(analyzed, template_file=parsed.template)
code = generator.run(analyzed, template_file=parsed.template)
sys.stdout.buffer.write(code)


Expand Down

0 comments on commit 572f2e9

Please sign in to comment.