Coverage for /builds/ase/ase/ase/db/project.py : 100.00%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from pathlib import Path
2from ase.db.row import row2dct
3from ase.formula import Formula
4from ase.db.core import KeyDescription
7class DatabaseProject:
8 """Settings for web view of a database.
10 For historical reasons called a "Project".
11 """
12 _ase_templates = Path('ase/db/templates')
14 def __init__(self, name, title, *,
15 key_descriptions,
16 database,
17 default_columns):
18 self.name = name
19 self.title = title
20 self.uid_key = 'id'
22 # The templates loop over "key descriptions" when they want to
23 # loop over keys.
24 #
25 # Therefore, any key without description will not be rendered.
26 # Therefore, we need to make dummy key descriptions of everything
27 # in the database, ensuring that all keys are visible.
28 #
29 # This is a very bad select() which loops over things that should be
30 # available directly, and also, it uses
31 # private variables of the row:
32 all_keys = set()
33 for row in database.select(
34 columns=['key_value_pairs'], include_data=False):
35 all_keys |= set(row._keys)
37 key_descriptions = {
38 **{key: KeyDescription(key) for key in all_keys},
39 **key_descriptions}
41 for key, value in key_descriptions.items():
42 assert isinstance(key, str), type(key)
43 assert isinstance(value, KeyDescription), type(value)
45 self.key_descriptions = key_descriptions
46 self.database = database
47 self.default_columns = default_columns
49 def get_search_template(self):
50 return self._ase_templates / 'search.html'
52 def get_row_template(self):
53 return self._ase_templates / 'row.html'
55 def get_table_template(self):
56 return self._ase_templates / 'table.html'
58 def handle_query(self, args) -> str:
59 """Convert request args to ase.db query string."""
60 return args['query']
62 def row_to_dict(self, row):
63 """Convert row to dict for use in html template."""
64 dct = row2dct(row, self.key_descriptions)
65 dct['formula'] = Formula(row.formula).convert('abc').format('html')
66 return dct
68 def uid_to_row(self, uid):
69 return self.database.get(f'{self.uid_key}={uid}')
71 @classmethod
72 def dummyproject(cls, **kwargs):
73 class DummyDatabase:
74 def select(self, *args, **kwargs):
75 return iter([])
77 _kwargs = dict(
78 name='test',
79 title='test',
80 key_descriptions={},
81 database=DummyDatabase(), # XXX
82 default_columns=[])
83 _kwargs.update(kwargs)
84 return cls(**_kwargs)
86 # If we make this a classmethod, and try to instantiate the class,
87 # it would fail on subclasses. So we use staticmethod
88 @staticmethod
89 def load_db_as_ase_project(name, database):
90 from ase.db.table import all_columns
91 from ase.db.core import get_key_descriptions
93 return DatabaseProject(
94 name=name,
95 title=database.metadata.get('title', ''),
96 key_descriptions=get_key_descriptions(),
97 database=database,
98 default_columns=all_columns)