SelectExamples
Repository source: SelectExamples
Description¶
This script allows you to obtain a list of examples corresponding to a particular VTK Class and a given language.
In order to do this, a JSON file listing the vtk examples by VTK class is obtained from the gh-pages branch of the vtk-examples GitHub site. When this script runs, it checks for the existence of this JSON file in your temporary folder, downloading it, if it doesn't exist. If it already exists, then it is updated if the file is more than ten minutes old.
When you run this script by specifying the VTK Class and Language (one of: CSharp
, Cxx
, Java
, Python
, PythonicAPI
), a list of links to the respective examples containing that class is returned. By default five or fewer examples are returned. If there are more than five examples for a class then five examples are randomly selected. You can override the maximum number of examples (e.g. -n20
) or select all examples -a
.
Note
Options are also provided to force an overwrite of the downloaded the JSON file (-o
) or to change the URL to the JSON file (-j
)
Other languages
See (Python)
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
SelectExamples.py
#!/usr/bin/env python3
import json
import os
import random
import tempfile
from datetime import datetime
from operator import itemgetter
from pathlib import Path
from urllib.error import HTTPError
from urllib.request import urlretrieve
def get_program_parameters():
import argparse
description = 'Get examples that use a particular VTK class for a given language.'
epilogue = '''
The JSON file needed by this script is obtained from the gh-pages branch
of the vtk-examples GitHub site.
It is stored in your tempfile directory.
If you change the URL to the JSON file, remember that there is a ten minute
wait before you can overwrite the last downloaded file. To force the download
specify -o on the command line.
Here is the URL for an alternative site for testing:
"https://raw.githubusercontent.com/ajpmaclean/web-test/gh-pages/src/Coverage/vtk_vtk-examples_xref.json"
'''
parser = argparse.ArgumentParser(description=description, epilog=epilogue,
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('vtk_class', help='The desired VTK class.')
parser.add_argument('language', help='The desired language, one of: CSharp, Cxx, Java, Python.')
parser.add_argument('-a', '--all_values', action="store_true",
help='All examples (Warning: Can be a very long list).')
parser.add_argument('-n', '--number', type=int, default=5, help='The maximum number of examples.')
parser.add_argument('-m', '--md', action='store_true',
help='Display links in markdown inline format e.g. [label](URL).')
parser.add_argument('-j', '--json_xref_url',
default='https://raw.githubusercontent.com/Kitware/vtk-examples/gh-pages/src/Coverage/vtk_vtk-examples_xref.json',
help='The URL for the JSON cross-reference file.')
parser.add_argument('-o', '--overwrite', action="store_true",
help='Force an initial download of the JSON cross-reference file.')
args = parser.parse_args()
return args.vtk_class, args.language, args.all_values, args.md, args.number, args.json_xref_url, args.overwrite
def download_file(dl_path, dl_url, overwrite=False):
"""
Use the URL to get a file.
:param dl_path: The path to download the file to.
:param dl_url: The URL of the file.
:param overwrite: If true, do a download even if the file exists.
:return: The path to the file as a pathlib Path.
"""
file_name = dl_url.split('/')[-1]
# Create necessary subdirectories in the dl_path
# (if they don't exist).
Path(dl_path).mkdir(parents=True, exist_ok=True)
# Download if it doesn't exist in the directory overriding if overwrite is True.
path = Path(dl_path, file_name)
if not path.is_file() or overwrite:
try:
urlretrieve(dl_url, path)
except HTTPError as e:
raise RuntimeError(f'Failed to download {dl_url}. {e.reason}')
return path
def get_examples(d, vtk_class, lang, all_values=False, number=5, md_fmt=False):
"""
For the VTK Class and language return the
total number of examples and a list of examples.
:param d: The dictionary.
:param vtk_class: The VTK Class e.g. vtkActor.
:param lang: The language, e.g. Cxx.
:param all_values: True if all examples are needed.
:param number: The number of values.
:param md_fmt: Use Markdown format with label and URL defined together.
:return: Total number of examples and a list of examples.
"""
try:
kv = d[vtk_class][lang].items()
except KeyError:
return None, None
if len(kv) > number:
if all_values:
samples = list(kv)
else:
samples = random.sample(list(kv), number)
else:
samples = kv
if md_fmt:
links = [f'[{s.rsplit("/", 1)[1]}]({s})' for s in sorted(map(itemgetter(1), samples))]
else:
links = sorted(map(itemgetter(1), samples))
return len(links), links
def get_crossref_dict(ref_dir, xref_url, overwrite=False):
"""
Download and return the json cross-reference file.
This function ensures that the dictionary is recent.
:param ref_dir: The directory where the file will be downloaded.
:param xref_url: The URL for the JSON cross-reference file.
:param overwrite: If true, do a download even if the file exists.
:return: The dictionary cross-referencing vtk classes to examples.
"""
path = download_file(ref_dir, xref_url, overwrite=overwrite)
if not path.is_file():
print(f'The path: {str(path)} does not exist.')
return None
dt = datetime.today().timestamp() - os.path.getmtime(path)
# Force a new download if the time difference is > 10 minutes.
if dt > 600:
path = download_file(ref_dir, xref_url, overwrite=True)
with open(path) as json_file:
return json.load(json_file)
def main():
vtk_class, language, all_values, md, number, xref_url, overwrite = get_program_parameters()
language = language.lower()
available_languages = {k.lower(): k for k in ['CSharp', 'Cxx', 'Java', 'Python', 'PythonicAPI']}
available_languages.update({'cpp': 'Cxx', 'c++': 'Cxx', 'c#': 'CSharp'})
if language not in available_languages:
print(f'The language: {language} is not available.')
tmp = ', '.join(sorted([lang for lang in set(available_languages.values())]))
print(f'Choose one of these: {tmp}.')
return
else:
language = available_languages[language]
xref_dict = get_crossref_dict(tempfile.gettempdir(), xref_url, overwrite)
if xref_dict is None:
print('The dictionary cross-referencing vtk classes to examples was not downloaded.')
return
total_number, examples = get_examples(xref_dict, vtk_class, language, all_values=all_values, number=number,
md_fmt=md)
if examples:
if total_number <= number or all_values:
print(f'VTK Class: {vtk_class}, language: {language}\n'
f'Number of example(s): {total_number}.')
else:
print(f'VTK Class: {vtk_class}, language: {language}\n'
f'Number of example(s): {total_number} with {number} random sample(s) shown.')
print('\n'.join(examples))
else:
print(f'No examples for the VTK Class: {vtk_class} and language: {language}')
if __name__ == '__main__':
main()